priorityqueue.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. // initial pseudocode from:
  2. // https://www.geeksforgeeks.org/binary-heap/
  3. #include <iostream>
  4. #include <cstdio>
  5. #include <string>
  6. #include "priorityqueue.h"
  7. #include "json.hpp"
  8. // priority queue class using binary heap
  9. void PriorityQueue::initiateHeap(int capacity){
  10. heap_size = 0;
  11. max_size = capacity;
  12. heapArray = new int[max_size];
  13. }
  14. void PriorityQueue::insert(int key){
  15. if(heap_size == max_size){
  16. std::cout << "PriorityQueue::insert called on full priority queue" << std::endl;
  17. return;
  18. }
  19. // increase array size and insert new key at end
  20. heap_size++;
  21. int keyIndex = heap_size;
  22. // heapify up until the heap properties are restored
  23. heapifyUp(key, keyIndex);
  24. }
  25. void PriorityQueue::deleteHeap(){
  26. // clean up memory so deallocate array
  27. delete[] heapArray;
  28. }
  29. void PriorityQueue::removeMax(){
  30. // check if heap is empty
  31. if (heap_size <= 0) {
  32. std::cout << "PriorityQueue::removeMax called on an empty priority queue" << std::endl;
  33. return;
  34. }
  35. if (heap_size == 1){
  36. //heapArray[0] == 0;
  37. heap_size--;
  38. } else if (heap_size == 2) { // need to check if at root to avoid error
  39. heapArray[1] = heapArray[2];
  40. heap_size--;
  41. } else {
  42. // remove the max value (at root)
  43. heapArray[1] = heapArray[heap_size];
  44. heapifyDown(1);
  45. heap_size--;
  46. }
  47. }
  48. int PriorityQueue::returnMax(){
  49. int topHeapKey = heapArray[1];
  50. return topHeapKey;
  51. }
  52. void PriorityQueue::removeKey(int key){
  53. for (int i = 1; i <= heap_size; i++) {
  54. if (heapArray[i] == key) {
  55. // swap the key at index with last heap key
  56. swap(&heapArray[i], &heapArray[heap_size]);
  57. // erase the last node erasing the unwanted key
  58. heap_size--;
  59. // heapify to preserve heap properties
  60. heapifyDown(i);
  61. return;
  62. }
  63. }
  64. std::cout << "PriorityQueue::removeKey key " << key << " not found" << std::endl;
  65. return;
  66. }
  67. void PriorityQueue::change(int key, int newKey){
  68. for (int i = 1; i <= heap_size; i++) {
  69. if (heapArray[i] == key) {
  70. heapArray[i] = newKey;
  71. if (newKey > key) {
  72. heapifyUp(newKey, i);
  73. return;
  74. } else if (newKey < key) {
  75. heapifyDown(i);
  76. return;
  77. }
  78. }
  79. }
  80. std::cout << "PriorityQueue::change key " << key << " not found" << std::endl;
  81. return;
  82. }
  83. void PriorityQueue::swap(int *key, int *newKey){
  84. for (int i = 1; i <= heap_size; i++) {
  85. if (heapArray[i] == *key) {
  86. int temp = *newKey;
  87. *newKey = *key;
  88. *key = temp;
  89. return;
  90. }
  91. }
  92. }
  93. void PriorityQueue::heapifyDown(int index){
  94. int lBranchIndex = 2*index;
  95. int rBranchIndex = 2*index + 1;
  96. int largerKeyIndex = index;
  97. if (lBranchIndex < heap_size && heapArray[lBranchIndex] > heapArray[index]) {
  98. largerKeyIndex = lBranchIndex;
  99. }
  100. if (rBranchIndex < heap_size && heapArray[rBranchIndex] > heapArray[largerKeyIndex]) {
  101. largerKeyIndex = rBranchIndex;
  102. }
  103. if (largerKeyIndex != index) {
  104. swap(&heapArray[index], &heapArray[largerKeyIndex]);
  105. heapifyDown(largerKeyIndex);
  106. }
  107. }
  108. void PriorityQueue::heapifyUp(int key, int index){
  109. int curIndex = index;
  110. int parentIndex = (curIndex)/2;
  111. // insert new key into the end of the array
  112. heapArray[curIndex] = key;
  113. while (curIndex != 1 && heapArray[parentIndex] < heapArray[curIndex]) {
  114. swap(&heapArray[curIndex], &heapArray[parentIndex]);
  115. curIndex = (curIndex)/2;
  116. parentIndex = (parentIndex)/2;
  117. }
  118. }
  119. void PriorityQueue::printArray(){
  120. for (int i = 1; i <= heap_size; i++) {
  121. std::cout << heapArray[i] << " , ";
  122. }
  123. std::cout << std::endl;
  124. }
  125. void PriorityQueue::printJSONTree(int maxHeapSize, int numOperations){
  126. nlohmann::json outputJSON; // output JSON file
  127. for (int i = heap_size; i >= 1; i--) {
  128. int keyValue = heapArray[i]; // get the key value at array index i
  129. // find index values for the left, right, and parent nodes
  130. int lBranchIndex = 2*i;
  131. int rBranchIndex = 2*i + 1;
  132. int parentIndex = i/2;
  133. // convert index and key into strings so as to put them in JSON output
  134. std::stringstream convert2String_i;
  135. convert2String_i << i;
  136. std::string indexForJSON = convert2String_i.str();
  137. std::stringstream convert2String_key;
  138. convert2String_key << keyValue;
  139. std::string keyForJSON = convert2String_key.str();
  140. outputJSON[indexForJSON]["key"] = keyForJSON;
  141. // if not at the root, find the index of the parent node
  142. if (i > 1) {
  143. std::stringstream convert2String_par;
  144. convert2String_par << parentIndex;
  145. std::string parentForJSON = convert2String_par.str();
  146. outputJSON[indexForJSON]["parent"] = parentForJSON;
  147. }
  148. // find if there is a left branch and if so, what the index is
  149. if (lBranchIndex <= heap_size) {
  150. std::stringstream convert2String_l;
  151. convert2String_l << lBranchIndex;
  152. std::string leftForJSON = convert2String_l.str();
  153. outputJSON[indexForJSON]["leftChild"] = leftForJSON;
  154. }
  155. // find if there is a right branch and if so, what the index is
  156. if (rBranchIndex <= heap_size) {
  157. std::stringstream convert2String_r;
  158. convert2String_r << rBranchIndex;
  159. std::string rightForJSON = convert2String_r.str();
  160. outputJSON[indexForJSON]["rightChild"] = rightForJSON;
  161. }
  162. }
  163. // write out the metadata output
  164. outputJSON["metadata"]["maxHeapSize"] = maxHeapSize;
  165. outputJSON["metadata"]["max_size"] = max_size;
  166. outputJSON["metadata"]["numOperations"] = numOperations;
  167. outputJSON["metadata"]["size"] = heap_size;
  168. std::cout << outputJSON << std::endl;
  169. }