/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see .
*/
/***********************************************************************************************
*** 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 ***
***********************************************************************************************
* *
* Project name : Buccaneer Bay *
* *
* File name : Binary_Heap.h *
* *
* Programmer : Mike Lytle *
* *
* Start date : 6/25/99 *
* *
* Last update : 6/25/99 *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BINARY_HEAP_CLASS_H
#define BINARY_HEAP_CLASS_H
/*=============================================================================================*/
// Includes.
/*=============================================================================================*/
#include
#include "bittype.h"
/*=============================================================================================*/
// Defines.
/*=============================================================================================*/
/*=============================================================================================*/
// Class declarations.
/*=============================================================================================*/
// WARNING!
// Any class used as an element of a heap for BinaryHeapClass must inherit HeapNodeClass.
template
class HeapNodeClass
{
public:
virtual uint32 Get_Heap_Location (void) const = 0;
virtual void Set_Heap_Location (uint32 location) = 0;
// This is pure virtual so that any type of key can be used as long as it uses the comparison operators.
virtual Key_Type Heap_Key (void) const = 0;
};
// WARNING!
// To reduce the number of compares, element [0] is a sentinel. It's key value must be the smallest or NULL.
// Keeps track of pointers to objects.
template
class BinaryHeapClass
{
public:
// This constructor uses elements that have already been allocated.
BinaryHeapClass(HeapNodeClass **allocated_list, unsigned int max_number_of_elements)
{
assert(allocated_list);
assert(max_number_of_elements > 0);
Elements = allocated_list;
Max_Number_Of_Elements = max_number_of_elements;
Number_Of_Elements = 0;
Own_Array = false;
}
// This constructor allocates its own array of nodes
BinaryHeapClass(unsigned int max_number_of_elements)
: Max_Number_Of_Elements (max_number_of_elements),
Number_Of_Elements (0),
Elements (NULL),
Own_Array (false)
{
Resize_Array (max_number_of_elements);
}
// The destructor simply ensures the array is freed (if needs be)
~BinaryHeapClass ()
{
Release_Array ();
}
// Reset all entries in the array to NULL
void Flush_Array (void)
{
::memset (Elements, NULL, sizeof (HeapNodeClass *) * Max_Number_Of_Elements);
Number_Of_Elements = 0;
}
// Reallocate an array large enough to hold the elements
void Resize_Array (unsigned int new_size)
{
// Start fresh
Release_Array ();
// Reallocate
Elements = new HeapNodeClass *[new_size];
Max_Number_Of_Elements = new_size;
Number_Of_Elements = 0;
Own_Array = true;
// Initialize to NULL
::memset (Elements, NULL, sizeof (HeapNodeClass *) * new_size);
return ;
}
void Release_Array (void)
{
if (Own_Array) {
delete [] Elements;
Elements = NULL;
Number_Of_Elements = 0;
Max_Number_Of_Elements = 0;
}
Own_Array = false;
return ;
}
// Return the current number of elements.
unsigned int Get_Number_Of_Elements()
{
return (Number_Of_Elements);
}
// Return the maximum number of elements.
unsigned int Get_Max_Number_Of_Elements (void)
{
return (Max_Number_Of_Elements);
}
// Return a pointer to a node in the tree
HeapNodeClass *Peek_Node (unsigned int location)
{
return Elements[location];
}
// Insert an element into the tree.
void Insert(HeapNodeClass *node)
{
// Increment the number of elements in the heap.
unsigned int i = ++Number_Of_Elements;
// Doesn't handle the case of adding more elements than there is memory for.
assert(Number_Of_Elements < Max_Number_Of_Elements);
// Find the elements's place in the tree. Remember: the smallest element is the root.
while (Greater_Than(Elements[i / 2], node))
{
Elements[i] = Elements[i / 2];
Elements[i]->Set_Heap_Location(i);
i /= 2;
}
Elements[i] = node;
Elements[i]->Set_Heap_Location(i);
}
// Move the element up in the tree if necessary. Use this if the key value becomes smaller when it is
// already in the heap.
void Percolate_Up(unsigned int location)
{
assert(location < Max_Number_Of_Elements);
unsigned int i = location;
HeapNodeClass *node = Elements[i];
// Find the elements's place in the tree. Remember: the smallest element is the root.
while (Greater_Than(Elements[i / 2], node))
{
Elements[i] = Elements[i / 2];
Elements[i]->Set_Heap_Location(i);
i /= 2;
}
Elements[i] = node;
Elements[i]->Set_Heap_Location(i);
}
// Take the smallest element out of the tree and reorder
HeapNodeClass* Remove_Min (void)
{
unsigned int child;
HeapNodeClass* last_element;
HeapNodeClass* min_element;
if (Number_Of_Elements == 0) {
return NULL;
}
assert(Number_Of_Elements > 0);
assert(Elements);
// The smallest element is always at this position.
min_element = Elements[1];
if (min_element != NULL) {
min_element->Set_Heap_Location (0);
}
last_element = Elements[Number_Of_Elements];
// Decrement the number of elements in the tree.
Number_Of_Elements--;
for (unsigned int i = 1; (i * 2) <= Number_Of_Elements; i = child)
{
// Find a smaller child.
child = i * 2;
if ((child != Number_Of_Elements) && (Less_Than(Elements[child + 1], Elements[child])))
{
child++;
}
// Percolate down one level.
if (Greater_Than(last_element, Elements[child]))
{
Elements[i] = Elements[child];
Elements[i]->Set_Heap_Location(i);
}
else
{
break;
}
}
Elements[i] = last_element;
Elements[i]->Set_Heap_Location(i);
return (min_element);
}
private:
bool Less_Than(HeapNodeClass *op1, HeapNodeClass *op2)
{
if (op1 == 0)
{
return (true);
}
if (op2 == 0)
{
return (false);
}
return (op1->Heap_Key() < op2->Heap_Key());
}
bool Less_Than_Equal(HeapNodeClass *op1, HeapNodeClass *op2)
{
if (op1 == 0)
{
return (true);
}
if (op2 == 0)
{
return (false);
}
return (op1->Heap_Key() <= op2->Heap_Key());
}
bool Greater_Than(HeapNodeClass *op1, HeapNodeClass *op2)
{
if (op1 == 0)
{
return (false);
}
if (op2 == 0)
{
return (true);
}
return (op1->Heap_Key() > op2->Heap_Key());
}
private:
// The list of elements.
HeapNodeClass **Elements;
// The number of allocated elements.
unsigned int Max_Number_Of_Elements;
// Current number of elements in the tree.
unsigned int Number_Of_Elements;
// Flag to indicate who owns the memory for the
// binary tree.
bool Own_Array;
};
#endif //BINARY_HEAP_CLASS_H