Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
binheap.h
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(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/***********************************************************************************************
20 *** 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 ***
21 ***********************************************************************************************
22 * *
23 * Project name : Buccaneer Bay *
24 * *
25 * File name : Binary_Heap.h *
26 * *
27 * Programmer : Mike Lytle *
28 * *
29 * Start date : 6/25/99 *
30 * *
31 * Last update : 6/25/99 *
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
36
37#ifndef BINARY_HEAP_CLASS_H
38#define BINARY_HEAP_CLASS_H
39
40/*=============================================================================================*/
41// Includes.
42/*=============================================================================================*/
43#include <assert.h>
44#include "bittype.h"
45
46/*=============================================================================================*/
47// Defines.
48/*=============================================================================================*/
49
50/*=============================================================================================*/
51// Class declarations.
52/*=============================================================================================*/
53// WARNING!
54// Any class used as an element of a heap for BinaryHeapClass must inherit HeapNodeClass.
55template <class Key_Type>
57{
58 public:
59
60 virtual uint32 Get_Heap_Location (void) const = 0;
61 virtual void Set_Heap_Location (uint32 location) = 0;
62
63 // This is pure virtual so that any type of key can be used as long as it uses the comparison operators.
64 virtual Key_Type Heap_Key (void) const = 0;
65
66};
67
68// WARNING!
69// To reduce the number of compares, element [0] is a sentinel. It's key value must be the smallest or NULL.
70// Keeps track of pointers to objects.
71template <class Key_Type>
73{
74 public:
75
76 // This constructor uses elements that have already been allocated.
77 BinaryHeapClass(HeapNodeClass<Key_Type> **allocated_list, unsigned int max_number_of_elements)
78 {
79 assert(allocated_list);
80 assert(max_number_of_elements > 0);
81
82 Elements = allocated_list;
83 Max_Number_Of_Elements = max_number_of_elements;
84 Number_Of_Elements = 0;
85 Own_Array = false;
86 }
87
88 // This constructor allocates its own array of nodes
89 BinaryHeapClass(unsigned int max_number_of_elements)
90 : Max_Number_Of_Elements (max_number_of_elements),
91 Number_Of_Elements (0),
92 Elements (NULL),
93 Own_Array (false)
94 {
95 Resize_Array (max_number_of_elements);
96 }
97
98 // The destructor simply ensures the array is freed (if needs be)
100 {
101 Release_Array ();
102 }
103
104 // Reset all entries in the array to NULL
105 void Flush_Array (void)
106 {
107 ::memset (Elements, NULL, sizeof (HeapNodeClass<Key_Type> *) * Max_Number_Of_Elements);
108 Number_Of_Elements = 0;
109 }
110
111 // Reallocate an array large enough to hold the elements
112 void Resize_Array (unsigned int new_size)
113 {
114 // Start fresh
115 Release_Array ();
116
117 // Reallocate
118 Elements = W3DNEWARRAY HeapNodeClass<Key_Type> *[new_size];
119 Max_Number_Of_Elements = new_size;
120 Number_Of_Elements = 0;
121 Own_Array = true;
122
123 // Initialize to NULL
124 ::memset (Elements, NULL, sizeof (HeapNodeClass<Key_Type> *) * new_size);
125 return ;
126 }
127
128 void Release_Array (void)
129 {
130 if (Own_Array) {
131 delete [] Elements;
132 Elements = NULL;
133 Number_Of_Elements = 0;
134 Max_Number_Of_Elements = 0;
135 }
136
137 Own_Array = false;
138 return ;
139 }
140
141 // Return the current number of elements.
143 {
144 return (Number_Of_Elements);
145 }
146
147 // Return the maximum number of elements.
148 unsigned int Get_Max_Number_Of_Elements (void)
149 {
150 return (Max_Number_Of_Elements);
151 }
152
153 // Return a pointer to a node in the tree
154 HeapNodeClass<Key_Type> *Peek_Node (unsigned int location)
155 {
156 return Elements[location];
157 }
158
159 // Insert an element into the tree.
161 {
162
163 // Increment the number of elements in the heap.
164 unsigned int i = ++Number_Of_Elements;
165
166 // Doesn't handle the case of adding more elements than there is memory for.
167 assert(Number_Of_Elements < Max_Number_Of_Elements);
168
169 // Find the elements's place in the tree. Remember: the smallest element is the root.
170 while (Greater_Than(Elements[i / 2], node))
171 {
172 Elements[i] = Elements[i / 2];
173 Elements[i]->Set_Heap_Location(i);
174 i /= 2;
175 }
176
177 Elements[i] = node;
178 Elements[i]->Set_Heap_Location(i);
179 }
180
181 // Move the element up in the tree if necessary. Use this if the key value becomes smaller when it is
182 // already in the heap.
183 void Percolate_Up(unsigned int location)
184 {
185 assert(location < Max_Number_Of_Elements);
186
187 unsigned int i = location;
188 HeapNodeClass<Key_Type> *node = Elements[i];
189
190 // Find the elements's place in the tree. Remember: the smallest element is the root.
191 while (Greater_Than(Elements[i / 2], node))
192 {
193 Elements[i] = Elements[i / 2];
194 Elements[i]->Set_Heap_Location(i);
195 i /= 2;
196 }
197
198 Elements[i] = node;
199 Elements[i]->Set_Heap_Location(i);
200 }
201
202 // Take the smallest element out of the tree and reorder
204 {
205 unsigned int child;
206 HeapNodeClass<Key_Type>* last_element;
207 HeapNodeClass<Key_Type>* min_element;
208
209 if (Number_Of_Elements == 0) {
210 return NULL;
211 }
212
213 assert(Number_Of_Elements > 0);
214 assert(Elements);
215
216 // The smallest element is always at this position.
217 min_element = Elements[1];
218 if (min_element != NULL) {
219 min_element->Set_Heap_Location (0);
220 }
221
222 last_element = Elements[Number_Of_Elements];
223
224 // Decrement the number of elements in the tree.
225 Number_Of_Elements--;
226
227 for (unsigned int i = 1; (i * 2) <= Number_Of_Elements; i = child)
228 {
229 // Find a smaller child.
230 child = i * 2;
231 if ((child != Number_Of_Elements) && (Less_Than(Elements[child + 1], Elements[child])))
232 {
233 child++;
234 }
235
236 // Percolate down one level.
237 if (Greater_Than(last_element, Elements[child]))
238 {
239 Elements[i] = Elements[child];
240 Elements[i]->Set_Heap_Location(i);
241 }
242 else
243 {
244 break;
245 }
246 }
247
248 Elements[i] = last_element;
249 Elements[i]->Set_Heap_Location(i);
250
251 return (min_element);
252 }
253
254 private:
255
256 bool Less_Than(HeapNodeClass<Key_Type> *op1, HeapNodeClass<Key_Type> *op2)
257 {
258 if (op1 == 0)
259 {
260 return (true);
261 }
262
263 if (op2 == 0)
264 {
265 return (false);
266 }
267
268 return (op1->Heap_Key() < op2->Heap_Key());
269 }
270
271 bool Less_Than_Equal(HeapNodeClass<Key_Type> *op1, HeapNodeClass<Key_Type> *op2)
272 {
273 if (op1 == 0)
274 {
275 return (true);
276 }
277
278 if (op2 == 0)
279 {
280 return (false);
281 }
282
283 return (op1->Heap_Key() <= op2->Heap_Key());
284 }
285
286
287 bool Greater_Than(HeapNodeClass<Key_Type> *op1, HeapNodeClass<Key_Type> *op2)
288 {
289 if (op1 == 0)
290 {
291 return (false);
292 }
293
294 if (op2 == 0)
295 {
296 return (true);
297 }
298
299 return (op1->Heap_Key() > op2->Heap_Key());
300 }
301
302 private:
303
304 // The list of elements.
305 HeapNodeClass<Key_Type> **Elements;
306
307 // The number of allocated elements.
308 unsigned int Max_Number_Of_Elements;
309
310 // Current number of elements in the tree.
311 unsigned int Number_Of_Elements;
312
313 // Flag to indicate who owns the memory for the
314 // binary tree.
315 bool Own_Array;
316};
317
318
319#endif //BINARY_HEAP_CLASS_H
#define NULL
Definition BaseType.h:92
#define W3DNEWARRAY
Definition always.h:110
unsigned long uint32
Definition bittype.h:46
@ false
Definition bool.h:59
HeapNodeClass< Key_Type > * Remove_Min(void)
Definition binheap.h:203
unsigned int Get_Max_Number_Of_Elements(void)
Definition binheap.h:148
void Release_Array(void)
Definition binheap.h:128
void Percolate_Up(unsigned int location)
Definition binheap.h:183
void Flush_Array(void)
Definition binheap.h:105
void Insert(HeapNodeClass< Key_Type > *node)
Definition binheap.h:160
BinaryHeapClass(unsigned int max_number_of_elements)
Definition binheap.h:89
BinaryHeapClass(HeapNodeClass< Key_Type > **allocated_list, unsigned int max_number_of_elements)
Definition binheap.h:77
HeapNodeClass< Key_Type > * Peek_Node(unsigned int location)
Definition binheap.h:154
unsigned int Get_Number_Of_Elements()
Definition binheap.h:142
void Resize_Array(unsigned int new_size)
Definition binheap.h:112
virtual void Set_Heap_Location(uint32 location)=0
virtual uint32 Get_Heap_Location(void) const =0
virtual Key_Type Heap_Key(void) const =0
else return(RetVal)