// initial pseudocode from: // https://www.geeksforgeeks.org/binary-heap/ #include #include #include #include "priorityqueue.h" #include "json.hpp" // priority queue class using binary heap void PriorityQueue::initiateHeap(int capacity){ heap_size = 0; max_size = capacity; heapArray = new int[max_size]; } void PriorityQueue::insert(int key){ if(heap_size == max_size){ std::cout << "PriorityQueue::insert called on full priority queue" << std::endl; return; } // increase array size and insert new key at end heap_size++; int keyIndex = heap_size; // heapify up until the heap properties are restored heapifyUp(key, keyIndex); } void PriorityQueue::deleteHeap(){ // clean up memory so deallocate array delete[] heapArray; } void PriorityQueue::removeMax(){ // check if heap is empty if (heap_size <= 0) { std::cout << "PriorityQueue::removeMax called on an empty priority queue" << std::endl; return; } if (heap_size == 1){ //heapArray[0] == 0; heap_size--; } else if (heap_size == 2) { // need to check if at root to avoid error heapArray[1] = heapArray[2]; heap_size--; } else { // remove the max value (at root) heapArray[1] = heapArray[heap_size]; heapifyDown(1); heap_size--; } } int PriorityQueue::returnMax(){ int topHeapKey = heapArray[1]; return topHeapKey; } void PriorityQueue::removeKey(int key){ for (int i = 1; i <= heap_size; i++) { if (heapArray[i] == key) { // swap the key at index with last heap key swap(&heapArray[i], &heapArray[heap_size]); // erase the last node erasing the unwanted key heap_size--; // heapify to preserve heap properties heapifyDown(i); return; } } std::cout << "PriorityQueue::removeKey key " << key << " not found" << std::endl; return; } void PriorityQueue::change(int key, int newKey){ for (int i = 1; i <= heap_size; i++) { if (heapArray[i] == key) { heapArray[i] = newKey; if (newKey > key) { heapifyUp(newKey, i); return; } else if (newKey < key) { heapifyDown(i); return; } } } std::cout << "PriorityQueue::change key " << key << " not found" << std::endl; return; } void PriorityQueue::swap(int *key, int *newKey){ for (int i = 1; i <= heap_size; i++) { if (heapArray[i] == *key) { int temp = *newKey; *newKey = *key; *key = temp; return; } } } void PriorityQueue::heapifyDown(int index){ int lBranchIndex = 2*index; int rBranchIndex = 2*index + 1; int largerKeyIndex = index; if (lBranchIndex < heap_size && heapArray[lBranchIndex] > heapArray[index]) { largerKeyIndex = lBranchIndex; } if (rBranchIndex < heap_size && heapArray[rBranchIndex] > heapArray[largerKeyIndex]) { largerKeyIndex = rBranchIndex; } if (largerKeyIndex != index) { swap(&heapArray[index], &heapArray[largerKeyIndex]); heapifyDown(largerKeyIndex); } } void PriorityQueue::heapifyUp(int key, int index){ int curIndex = index; int parentIndex = (curIndex)/2; // insert new key into the end of the array heapArray[curIndex] = key; while (curIndex != 1 && heapArray[parentIndex] < heapArray[curIndex]) { swap(&heapArray[curIndex], &heapArray[parentIndex]); curIndex = (curIndex)/2; parentIndex = (parentIndex)/2; } } void PriorityQueue::printArray(){ for (int i = 1; i <= heap_size; i++) { std::cout << heapArray[i] << " , "; } std::cout << std::endl; } void PriorityQueue::printJSONTree(int maxHeapSize, int numOperations){ nlohmann::json outputJSON; // output JSON file for (int i = heap_size; i >= 1; i--) { int keyValue = heapArray[i]; // get the key value at array index i // find index values for the left, right, and parent nodes int lBranchIndex = 2*i; int rBranchIndex = 2*i + 1; int parentIndex = i/2; // convert index and key into strings so as to put them in JSON output std::stringstream convert2String_i; convert2String_i << i; std::string indexForJSON = convert2String_i.str(); std::stringstream convert2String_key; convert2String_key << keyValue; std::string keyForJSON = convert2String_key.str(); outputJSON[indexForJSON]["key"] = keyForJSON; // if not at the root, find the index of the parent node if (i > 1) { std::stringstream convert2String_par; convert2String_par << parentIndex; std::string parentForJSON = convert2String_par.str(); outputJSON[indexForJSON]["parent"] = parentForJSON; } // find if there is a left branch and if so, what the index is if (lBranchIndex <= heap_size) { std::stringstream convert2String_l; convert2String_l << lBranchIndex; std::string leftForJSON = convert2String_l.str(); outputJSON[indexForJSON]["leftChild"] = leftForJSON; } // find if there is a right branch and if so, what the index is if (rBranchIndex <= heap_size) { std::stringstream convert2String_r; convert2String_r << rBranchIndex; std::string rightForJSON = convert2String_r.str(); outputJSON[indexForJSON]["rightChild"] = rightForJSON; } } // write out the metadata output outputJSON["metadata"]["maxHeapSize"] = maxHeapSize; outputJSON["metadata"]["max_size"] = max_size; outputJSON["metadata"]["numOperations"] = numOperations; outputJSON["metadata"]["size"] = heap_size; std::cout << outputJSON << std::endl; }