Codechange: use std::vector instead of malloced array

This commit is contained in:
Rubidium 2024-05-12 09:47:14 +02:00 committed by rubidium42
parent 6cea49c117
commit 77c188e6da

View File

@ -10,8 +10,6 @@
#ifndef BINARYHEAP_HPP
#define BINARYHEAP_HPP
#include "../core/alloc_func.hpp"
/** Enable it if you suspect binary heap doesn't work well */
#define BINARYHEAP_CHECK 0
@ -27,7 +25,11 @@
* Binary Heap as C++ template.
* A carrier which keeps its items automatically holds the smallest item at
* the first position. The order of items is maintained by using a binary tree.
* The implementation is used for priority queue's.
* The implementation is used for priority queues.
*
* There are two major differences compared to std::priority_queue. First the
* std::priority_queue does not support indexing/removing elements in the
* middle of the heap/queue and second it has the biggest item first.
*
* @par Usage information:
* Item of the binary heap should support the 'lower-than' operator '<'.
@ -50,27 +52,18 @@
template <class T>
class CBinaryHeapT {
private:
size_t items; ///< Number of items in the heap
size_t capacity; ///< Maximum number of items the heap can hold
T **data; ///< The pointer to the heap item pointers
size_t items = 0; ///< Number of valid items in the heap
std::vector<T *> data; ///< The pointer to the heap item pointers
public:
/**
* Create a binary heap.
* @param max_items The limit of the heap
* @param initial_capacity The initial reserved capacity for the heap.
*/
explicit CBinaryHeapT(size_t max_items)
: items(0)
, capacity(max_items)
{
this->data = MallocT<T *>(max_items + 1);
}
~CBinaryHeapT()
explicit CBinaryHeapT(size_t initial_capacity)
{
this->data.reserve(initial_capacity);
this->Clear();
free(this->data);
this->data = nullptr;
}
protected:
@ -142,6 +135,7 @@ protected:
/** Verify the heap consistency */
inline void CheckConsistency()
{
assert(this->items == this->data.size() - 1);
for (size_t child = 2; child <= this->items; child++) {
size_t parent = child / 2;
assert(!(*this->data[child] < *this->data[parent]));
@ -170,16 +164,6 @@ public:
return this->items == 0;
}
/**
* Test if the priority queue is full.
*
* @return True if full.
*/
inline bool IsFull() const
{
return this->items >= this->capacity;
}
/**
* Get the smallest item in the binary tree.
*
@ -210,14 +194,8 @@ public:
*/
inline void Include(T *new_item)
{
if (this->IsFull()) {
assert(this->capacity < UINT_MAX / 2);
this->capacity *= 2;
this->data = ReallocT<T*>(this->data, this->capacity + 1);
}
/* Make place for new item. A gap is now at the end of the tree. */
this->data.emplace_back();
size_t gap = this->HeapifyUp(++items, new_item);
this->data[gap] = new_item;
CHECK_CONSISTY();
@ -241,6 +219,7 @@ public:
size_t gap = this->HeapifyDown(1, last);
/* move last item to the proper place */
if (!this->IsEmpty()) this->data[gap] = last;
this->data.pop_back();
CHECK_CONSISTY();
return first;
@ -268,6 +247,8 @@ public:
assert(index == this->items);
this->items--;
}
this->data.pop_back();
CHECK_CONSISTY();
}
@ -281,13 +262,8 @@ public:
*/
inline size_t FindIndex(const T &item) const
{
if (this->IsEmpty()) return 0;
for (T **ppI = this->data + 1, **ppLast = ppI + this->items; ppI <= ppLast; ppI++) {
if (*ppI == &item) {
return ppI - this->data;
}
}
return 0;
auto it = std::find(this->data.begin(), this->data.end(), &item);
return it == this->data.end() ? 0 : std::distance(this->data.begin(), it);
}
/**
@ -297,6 +273,9 @@ public:
inline void Clear()
{
this->items = 0;
this->data.resize(1);
CHECK_CONSISTY();
}
};