priorityqueue.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* Priority queue class to build heap array
  2. Code from Geeks for Geeks (https://www.geeksforgeeks.org/binary-heap/) used as a starting point
  3. */
  4. #include <iostream>
  5. #include <cstdio>
  6. #include <string>
  7. #include "priorityqueue.h"
  8. #include "json.hpp"
  9. //
  10. void PriorityQueue::initiateHeap(int capacity){
  11. heap_size = 0;
  12. max_size = capacity;
  13. heapArray = new int[max_size + 1];
  14. }
  15. // inserts a new key into end of heap array to then
  16. void PriorityQueue::insert(int key){
  17. if(heap_size == max_size){
  18. std::cout << "PriorityQueue::insert called on full priority queue" << std::endl;
  19. return;
  20. }
  21. heap_size++;
  22. heapArray[heap_size] = key;
  23. heapifyUp(heap_size);
  24. }
  25. // clean up memory to avoid memory leaks
  26. void PriorityQueue::deleteHeap(){
  27. delete[] heapArray;
  28. }
  29. void PriorityQueue::removeMax(){
  30. if (heap_size <= 0) {
  31. std::cout << "PriorityQueue::removeMax called on an empty priority queue" << std::endl;
  32. return;
  33. }
  34. if (heap_size == 1){
  35. heap_size--;
  36. } else if (heap_size == 2) {
  37. heapArray[1] = heapArray[2];
  38. heap_size--;
  39. } else {
  40. heapArray[1] = heapArray[heap_size];
  41. heap_size--;
  42. heapifyDown(1);
  43. }
  44. }
  45. int PriorityQueue::returnMax(){
  46. int topHeapKey = heapArray[1];
  47. return topHeapKey;
  48. }
  49. void PriorityQueue::removeKey(int key){
  50. for (int i = 1; i <= heap_size; i++) {
  51. if (heapArray[i] == key) {
  52. int beforeValue = heapArray[i];
  53. int afterValue = heapArray[heap_size];
  54. swap(&heapArray[i], &heapArray[heap_size]);
  55. heap_size--;
  56. if (beforeValue == afterValue) {
  57. return;
  58. } else if (afterValue < beforeValue) {
  59. heapifyDown(i);
  60. return;
  61. } else if (afterValue > beforeValue) {
  62. heapifyUp(i);
  63. return;
  64. }
  65. }
  66. }
  67. std::cout << "PriorityQueue::removeKey key " << key << " not found" << std::endl;
  68. }
  69. void PriorityQueue::change(int key, int newKey){
  70. for (int i = 1; i <= heap_size; i++) {
  71. if (heapArray[i] == key) {
  72. heapArray[i] = newKey;
  73. if (key == newKey) {
  74. return;
  75. } else if (newKey > key) {
  76. heapifyUp(i);
  77. return;
  78. } else if (newKey < key) {
  79. heapifyDown(i);
  80. return;
  81. }
  82. }
  83. }
  84. std::cout << "PriorityQueue::change key " << key << " not found" << std::endl;
  85. }
  86. void PriorityQueue::swap(int *key, int *otherKey){
  87. int temp = *otherKey;
  88. *otherKey = *key;
  89. *key = temp;
  90. }
  91. void PriorityQueue::heapifyDown(int index){
  92. int lBranchIndex = 2*index;
  93. int rBranchIndex = 2*index + 1;
  94. int largerKeyIndex = index;
  95. if (lBranchIndex <= heap_size && heapArray[lBranchIndex] > heapArray[largerKeyIndex]) {
  96. largerKeyIndex = lBranchIndex;
  97. }
  98. if (rBranchIndex <= heap_size && heapArray[rBranchIndex] > heapArray[largerKeyIndex]) {
  99. largerKeyIndex = rBranchIndex;
  100. }
  101. if (largerKeyIndex != index) {
  102. swap(&heapArray[index], &heapArray[largerKeyIndex]);
  103. heapifyDown(largerKeyIndex);
  104. }
  105. }
  106. void PriorityQueue::heapifyUp(int index){
  107. if (index <= 1){
  108. return;
  109. }
  110. int curIndex = index;
  111. int parentIndex = (curIndex)/2;
  112. while (parentIndex > 0 && heapArray[parentIndex] < heapArray[curIndex]) {
  113. swap(&heapArray[parentIndex], &heapArray[curIndex]);
  114. curIndex = (curIndex)/2;
  115. parentIndex = (parentIndex)/2;
  116. }
  117. }
  118. void PriorityQueue::printJSONTree(int maxHeapSize, int numOperations){
  119. nlohmann::json outputJSON;
  120. for (int i = heap_size; i >= 1; i--) {
  121. int keyValue = heapArray[i];
  122. int lBranchIndex = 2*i;
  123. int rBranchIndex = 2*i + 1;
  124. int parentIndex = i/2;
  125. std::stringstream convert2String_i;
  126. convert2String_i << i;
  127. std::string indexForJSON = convert2String_i.str();
  128. outputJSON[indexForJSON]["key"] = keyValue;
  129. // if not at the root, find the index of the parent node
  130. if (i > 1) {
  131. outputJSON[indexForJSON]["parent"] = parentIndex;
  132. }
  133. // is there a left branch
  134. if (lBranchIndex <= heap_size) {
  135. outputJSON[indexForJSON]["leftChild"] = lBranchIndex;
  136. }
  137. // is there a right branch
  138. if (rBranchIndex <= heap_size) {
  139. outputJSON[indexForJSON]["rightChild"] = rBranchIndex;
  140. }
  141. }
  142. // metadata output
  143. outputJSON["metadata"]["maxHeapSize"] = maxHeapSize;
  144. outputJSON["metadata"]["max_size"] = max_size;
  145. outputJSON["metadata"]["numOperations"] = numOperations;
  146. outputJSON["metadata"]["size"] = heap_size;
  147. std::cout << outputJSON << std::endl;
  148. }