| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- // based off of:
- // https://www.geeksforgeeks.org/binary-heap/
- #include <iostream>
- #include <cstdio>
- #include <string>
- #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 + 1];
- }
- 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 of array
- heap_size++;
- heapArray[heap_size] = key;
- // heapify up until the heap properties are restored
- heapifyUp(heap_size);
- }
- 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){
- 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];
- 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 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
- 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;
- // move new key value to the correct location using heapify up/down
- if (key == newKey) {
- return;
- } else if (newKey > key) {
- heapifyUp(i);
- return;
- } else if (newKey < key) {
- heapifyDown(i);
- return;
- }
- }
- }
- // if the key value could not be found, the method returns an error message
- 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; // 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();
- outputJSON[indexForJSON]["key"] = keyValue;
- // if not at the root, find the index of the parent node
- if (i > 1) {
- outputJSON[indexForJSON]["parent"] = parentIndex;
- }
- // find if there is a left branch and if so, what the index is
- if (lBranchIndex <= heap_size) {
- outputJSON[indexForJSON]["leftChild"] = lBranchIndex;
- }
- // find if there is a right branch and if so, what the index is
- if (rBranchIndex <= heap_size) {
- outputJSON[indexForJSON]["rightChild"] = rBranchIndex;
- }
- }
- // 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;
- }
|