binheap.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project name : Buccaneer Bay *
  23. * *
  24. * File name : Binary_Heap.h *
  25. * *
  26. * Programmer : Mike Lytle *
  27. * *
  28. * Start date : 6/25/99 *
  29. * *
  30. * Last update : 6/25/99 *
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #ifndef BINARY_HEAP_CLASS_H
  36. #define BINARY_HEAP_CLASS_H
  37. /*=============================================================================================*/
  38. // Includes.
  39. /*=============================================================================================*/
  40. #include <assert.h>
  41. #include "bittype.h"
  42. /*=============================================================================================*/
  43. // Defines.
  44. /*=============================================================================================*/
  45. /*=============================================================================================*/
  46. // Class declarations.
  47. /*=============================================================================================*/
  48. // WARNING!
  49. // Any class used as an element of a heap for BinaryHeapClass must inherit HeapNodeClass.
  50. template <class Key_Type>
  51. class HeapNodeClass
  52. {
  53. public:
  54. virtual uint32 Get_Heap_Location (void) const = 0;
  55. virtual void Set_Heap_Location (uint32 location) = 0;
  56. // This is pure virtual so that any type of key can be used as long as it uses the comparison operators.
  57. virtual Key_Type Heap_Key (void) const = 0;
  58. };
  59. // WARNING!
  60. // To reduce the number of compares, element [0] is a sentinel. It's key value must be the smallest or NULL.
  61. // Keeps track of pointers to objects.
  62. template <class Key_Type>
  63. class BinaryHeapClass
  64. {
  65. public:
  66. // This constructor uses elements that have already been allocated.
  67. BinaryHeapClass(HeapNodeClass<Key_Type> **allocated_list, unsigned int max_number_of_elements)
  68. {
  69. assert(allocated_list);
  70. assert(max_number_of_elements > 0);
  71. Elements = allocated_list;
  72. Max_Number_Of_Elements = max_number_of_elements;
  73. Number_Of_Elements = 0;
  74. Own_Array = false;
  75. }
  76. // This constructor allocates its own array of nodes
  77. BinaryHeapClass(unsigned int max_number_of_elements)
  78. : Max_Number_Of_Elements (max_number_of_elements),
  79. Number_Of_Elements (0),
  80. Elements (NULL),
  81. Own_Array (false)
  82. {
  83. Resize_Array (max_number_of_elements);
  84. }
  85. // The destructor simply ensures the array is freed (if needs be)
  86. ~BinaryHeapClass ()
  87. {
  88. Release_Array ();
  89. }
  90. // Reset all entries in the array to NULL
  91. void Flush_Array (void)
  92. {
  93. ::memset (Elements, NULL, sizeof (HeapNodeClass<Key_Type> *) * Max_Number_Of_Elements);
  94. Number_Of_Elements = 0;
  95. }
  96. // Reallocate an array large enough to hold the elements
  97. void Resize_Array (unsigned int new_size)
  98. {
  99. // Start fresh
  100. Release_Array ();
  101. // Reallocate
  102. Elements = W3DNEWARRAY HeapNodeClass<Key_Type> *[new_size];
  103. Max_Number_Of_Elements = new_size;
  104. Number_Of_Elements = 0;
  105. Own_Array = true;
  106. // Initialize to NULL
  107. ::memset (Elements, NULL, sizeof (HeapNodeClass<Key_Type> *) * new_size);
  108. return ;
  109. }
  110. void Release_Array (void)
  111. {
  112. if (Own_Array) {
  113. delete [] Elements;
  114. Elements = NULL;
  115. Number_Of_Elements = 0;
  116. Max_Number_Of_Elements = 0;
  117. }
  118. Own_Array = false;
  119. return ;
  120. }
  121. // Return the current number of elements.
  122. unsigned int Get_Number_Of_Elements()
  123. {
  124. return (Number_Of_Elements);
  125. }
  126. // Return the maximum number of elements.
  127. unsigned int Get_Max_Number_Of_Elements (void)
  128. {
  129. return (Max_Number_Of_Elements);
  130. }
  131. // Return a pointer to a node in the tree
  132. HeapNodeClass<Key_Type> *Peek_Node (unsigned int location)
  133. {
  134. return Elements[location];
  135. }
  136. // Insert an element into the tree.
  137. void Insert(HeapNodeClass<Key_Type> *node)
  138. {
  139. // Increment the number of elements in the heap.
  140. unsigned int i = ++Number_Of_Elements;
  141. // Doesn't handle the case of adding more elements than there is memory for.
  142. assert(Number_Of_Elements < Max_Number_Of_Elements);
  143. // Find the elements's place in the tree. Remember: the smallest element is the root.
  144. while (Greater_Than(Elements[i / 2], node))
  145. {
  146. Elements[i] = Elements[i / 2];
  147. Elements[i]->Set_Heap_Location(i);
  148. i /= 2;
  149. }
  150. Elements[i] = node;
  151. Elements[i]->Set_Heap_Location(i);
  152. }
  153. // Move the element up in the tree if necessary. Use this if the key value becomes smaller when it is
  154. // already in the heap.
  155. void Percolate_Up(unsigned int location)
  156. {
  157. assert(location < Max_Number_Of_Elements);
  158. unsigned int i = location;
  159. HeapNodeClass<Key_Type> *node = Elements[i];
  160. // Find the elements's place in the tree. Remember: the smallest element is the root.
  161. while (Greater_Than(Elements[i / 2], node))
  162. {
  163. Elements[i] = Elements[i / 2];
  164. Elements[i]->Set_Heap_Location(i);
  165. i /= 2;
  166. }
  167. Elements[i] = node;
  168. Elements[i]->Set_Heap_Location(i);
  169. }
  170. // Take the smallest element out of the tree and reorder
  171. HeapNodeClass<Key_Type>* Remove_Min (void)
  172. {
  173. unsigned int child;
  174. HeapNodeClass<Key_Type>* last_element;
  175. HeapNodeClass<Key_Type>* min_element;
  176. if (Number_Of_Elements == 0) {
  177. return NULL;
  178. }
  179. assert(Number_Of_Elements > 0);
  180. assert(Elements);
  181. // The smallest element is always at this position.
  182. min_element = Elements[1];
  183. if (min_element != NULL) {
  184. min_element->Set_Heap_Location (0);
  185. }
  186. last_element = Elements[Number_Of_Elements];
  187. // Decrement the number of elements in the tree.
  188. Number_Of_Elements--;
  189. for (unsigned int i = 1; (i * 2) <= Number_Of_Elements; i = child)
  190. {
  191. // Find a smaller child.
  192. child = i * 2;
  193. if ((child != Number_Of_Elements) && (Less_Than(Elements[child + 1], Elements[child])))
  194. {
  195. child++;
  196. }
  197. // Percolate down one level.
  198. if (Greater_Than(last_element, Elements[child]))
  199. {
  200. Elements[i] = Elements[child];
  201. Elements[i]->Set_Heap_Location(i);
  202. }
  203. else
  204. {
  205. break;
  206. }
  207. }
  208. Elements[i] = last_element;
  209. Elements[i]->Set_Heap_Location(i);
  210. return (min_element);
  211. }
  212. private:
  213. bool Less_Than(HeapNodeClass<Key_Type> *op1, HeapNodeClass<Key_Type> *op2)
  214. {
  215. if (op1 == 0)
  216. {
  217. return (true);
  218. }
  219. if (op2 == 0)
  220. {
  221. return (false);
  222. }
  223. return (op1->Heap_Key() < op2->Heap_Key());
  224. }
  225. bool Less_Than_Equal(HeapNodeClass<Key_Type> *op1, HeapNodeClass<Key_Type> *op2)
  226. {
  227. if (op1 == 0)
  228. {
  229. return (true);
  230. }
  231. if (op2 == 0)
  232. {
  233. return (false);
  234. }
  235. return (op1->Heap_Key() <= op2->Heap_Key());
  236. }
  237. bool Greater_Than(HeapNodeClass<Key_Type> *op1, HeapNodeClass<Key_Type> *op2)
  238. {
  239. if (op1 == 0)
  240. {
  241. return (false);
  242. }
  243. if (op2 == 0)
  244. {
  245. return (true);
  246. }
  247. return (op1->Heap_Key() > op2->Heap_Key());
  248. }
  249. private:
  250. // The list of elements.
  251. HeapNodeClass<Key_Type> **Elements;
  252. // The number of allocated elements.
  253. unsigned int Max_Number_Of_Elements;
  254. // Current number of elements in the tree.
  255. unsigned int Number_Of_Elements;
  256. // Flag to indicate who owns the memory for the
  257. // binary tree.
  258. bool Own_Array;
  259. };
  260. #endif //BINARY_HEAP_CLASS_H