1
0
Fork 0

Codechange: use std::vector instead of malloced array

pull/12647/merge
Rubidium 2024-05-12 09:47:14 +02:00 committed by rubidium42
parent 6cea49c117
commit 77c188e6da
1 changed files with 20 additions and 41 deletions

View File

@ -10,8 +10,6 @@
#ifndef BINARYHEAP_HPP #ifndef BINARYHEAP_HPP
#define BINARYHEAP_HPP #define BINARYHEAP_HPP
#include "../core/alloc_func.hpp"
/** Enable it if you suspect binary heap doesn't work well */ /** Enable it if you suspect binary heap doesn't work well */
#define BINARYHEAP_CHECK 0 #define BINARYHEAP_CHECK 0
@ -27,7 +25,11 @@
* Binary Heap as C++ template. * Binary Heap as C++ template.
* A carrier which keeps its items automatically holds the smallest item at * 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 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: * @par Usage information:
* Item of the binary heap should support the 'lower-than' operator '<'. * Item of the binary heap should support the 'lower-than' operator '<'.
@ -50,27 +52,18 @@
template <class T> template <class T>
class CBinaryHeapT { class CBinaryHeapT {
private: private:
size_t items; ///< Number of items in the heap size_t items = 0; ///< Number of valid items in the heap
size_t capacity; ///< Maximum number of items the heap can hold std::vector<T *> data; ///< The pointer to the heap item pointers
T **data; ///< The pointer to the heap item pointers
public: public:
/** /**
* Create a binary heap. * 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) explicit CBinaryHeapT(size_t initial_capacity)
: items(0)
, capacity(max_items)
{
this->data = MallocT<T *>(max_items + 1);
}
~CBinaryHeapT()
{ {
this->data.reserve(initial_capacity);
this->Clear(); this->Clear();
free(this->data);
this->data = nullptr;
} }
protected: protected:
@ -142,6 +135,7 @@ protected:
/** Verify the heap consistency */ /** Verify the heap consistency */
inline void CheckConsistency() inline void CheckConsistency()
{ {
assert(this->items == this->data.size() - 1);
for (size_t child = 2; child <= this->items; child++) { for (size_t child = 2; child <= this->items; child++) {
size_t parent = child / 2; size_t parent = child / 2;
assert(!(*this->data[child] < *this->data[parent])); assert(!(*this->data[child] < *this->data[parent]));
@ -170,16 +164,6 @@ public:
return this->items == 0; 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. * Get the smallest item in the binary tree.
* *
@ -210,14 +194,8 @@ public:
*/ */
inline void Include(T *new_item) 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. */ /* 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); size_t gap = this->HeapifyUp(++items, new_item);
this->data[gap] = new_item; this->data[gap] = new_item;
CHECK_CONSISTY(); CHECK_CONSISTY();
@ -241,6 +219,7 @@ public:
size_t gap = this->HeapifyDown(1, last); size_t gap = this->HeapifyDown(1, last);
/* move last item to the proper place */ /* move last item to the proper place */
if (!this->IsEmpty()) this->data[gap] = last; if (!this->IsEmpty()) this->data[gap] = last;
this->data.pop_back();
CHECK_CONSISTY(); CHECK_CONSISTY();
return first; return first;
@ -268,6 +247,8 @@ public:
assert(index == this->items); assert(index == this->items);
this->items--; this->items--;
} }
this->data.pop_back();
CHECK_CONSISTY(); CHECK_CONSISTY();
} }
@ -281,13 +262,8 @@ public:
*/ */
inline size_t FindIndex(const T &item) const inline size_t FindIndex(const T &item) const
{ {
if (this->IsEmpty()) return 0; auto it = std::find(this->data.begin(), this->data.end(), &item);
for (T **ppI = this->data + 1, **ppLast = ppI + this->items; ppI <= ppLast; ppI++) { return it == this->data.end() ? 0 : std::distance(this->data.begin(), it);
if (*ppI == &item) {
return ppI - this->data;
}
}
return 0;
} }
/** /**
@ -297,6 +273,9 @@ public:
inline void Clear() inline void Clear()
{ {
this->items = 0; this->items = 0;
this->data.resize(1);
CHECK_CONSISTY();
} }
}; };