/* Priority queue class to build heap array Code from Geeks for Geeks (https://www.geeksforgeeks.org/binary-heap/) used as a starting point */ #include #include #include #include "priorityqueue.h" #include "json.hpp" // void PriorityQueue::initiateHeap(int capacity){ heap_size = 0; max_size = capacity; heapArray = new int[max_size + 1]; } // inserts a new key into end of heap array to then void PriorityQueue::insert(int key){ if(heap_size == max_size){ std::cout << "PriorityQueue::insert called on full priority queue" << std::endl; return; } heap_size++; heapArray[heap_size] = key; heapifyUp(heap_size); } // clean up memory to avoid memory leaks void PriorityQueue::deleteHeap(){ delete[] heapArray; } void PriorityQueue::removeMax(){ if (heap_size <= 0) { std::cout << "PriorityQueue::removeMax called on an empty priority queue" << std::endl; return; } if (heap_size == 1){ heap_size--; } else if (heap_size == 2) { heapArray[1] = heapArray[2]; heap_size--; } else { heapArray[1] = heapArray[heap_size]; heap_size--; heapifyDown(1); } } 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) { int beforeValue = heapArray[i]; int afterValue = heapArray[heap_size]; swap(&heapArray[i], &heapArray[heap_size]); heap_size--; if (beforeValue == afterValue) { return; } else if (afterValue < beforeValue) { heapifyDown(i); return; } else if (afterValue > beforeValue) { heapifyUp(i); return; } } } std::cout << "PriorityQueue::removeKey key " << key << " not found" << std::endl; } void PriorityQueue::change(int key, int newKey){ for (int i = 1; i <= heap_size; i++) { if (heapArray[i] == key) { heapArray[i] = newKey; if (key == newKey) { return; } else if (newKey > key) { heapifyUp(i); return; } else if (newKey < key) { heapifyDown(i); return; } } } std::cout << "PriorityQueue::change key " << key << " not found" << std::endl; } void PriorityQueue::swap(int *key, int *otherKey){ int temp = *otherKey; *otherKey = *key; *key = temp; } void PriorityQueue::heapifyDown(int index){ int lBranchIndex = 2*index; int rBranchIndex = 2*index + 1; int largerKeyIndex = index; if (lBranchIndex <= heap_size && heapArray[lBranchIndex] > heapArray[largerKeyIndex]) { 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 index){ if (index <= 1){ return; } int curIndex = index; int parentIndex = (curIndex)/2; while (parentIndex > 0 && heapArray[parentIndex] < heapArray[curIndex]) { swap(&heapArray[parentIndex], &heapArray[curIndex]); curIndex = (curIndex)/2; parentIndex = (parentIndex)/2; } } void PriorityQueue::printJSONTree(int maxHeapSize, int numOperations){ nlohmann::json outputJSON; for (int i = heap_size; i >= 1; i--) { int keyValue = heapArray[i]; int lBranchIndex = 2*i; int rBranchIndex = 2*i + 1; int parentIndex = i/2; std::stringstream convert2String_i; convert2String_i << i; std::string indexForJSON = convert2String_i.str(); outputJSON[indexForJSON]["key"] = keyValue; // if not at the root, find the index of the parent node if (i > 1) { outputJSON[indexForJSON]["parent"] = parentIndex; } // is there a left branch if (lBranchIndex <= heap_size) { outputJSON[indexForJSON]["leftChild"] = lBranchIndex; } // is there a right branch if (rBranchIndex <= heap_size) { outputJSON[indexForJSON]["rightChild"] = rBranchIndex; } } // 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; }