- #ifndef _BHEAP
- #define _BHEAP
- namespace alg{
- template<class T, class Equal, class Less> class BHeap{
- private:
- T* nodes;
- int max_capcity;
- int current_size;
- Equal cmp;
- Less less;
- inline int leftIndex(const int& idx)
- {
- return (idx << 1) + 1;
- }
- inline int rightIndex(const int& idx)
- {
- return (idx << 1) + 2;
- }
- inline int parentIndex(const int& idx)
- {
- return (idx - 1) >> 1;
- }
- bool realloc(const int&);
- public:
- BHeap(const int&);
- ~BHeap(void);
- bool push(T);
- T pop(void);
- void shift(const int&);
- void clear(void);
- int find(const T);
- const T& operator[](const int&) const;
- T& operator[](const int&);
- inline T first(void)
- {
- if(!empty())
- return nodes[0];
- else
- return 0;
- }
- inline bool empty(void)
- {
- return !current_size;
- }
- inline int size(void)
- {
- return current_size;
- }
- };
- template<class T, class Equal, class Less>
- BHeap<T,Equal,Less>::BHeap(const int& max_capcity)
- {
- this->max_capcity = max_capcity > 32 ? max_capcity : 32;
- current_size = 0;
- nodes = new T[this->max_capcity];
- }
- template<class T, class Equal, class Less>
- BHeap<T,Equal,Less>::~BHeap(void)
- {
- if(nodes != 0)
- delete []nodes;
- }
- template<class T, class Equal, class Less>
- void BHeap<T,Equal,Less>::clear(void)
- {
- if(nodes != 0)
- delete []nodes;
- nodes = new T[max_capcity];
- current_size = 0;
- }
- template<class T, class Equal, class Less>
- bool BHeap<T,Equal,Less>::push(T val)
- {
- if(current_size == max_capcity){
- realloc(max_capcity + (max_capcity >> 1));
- }
- nodes[++current_size - 1] = val;
- int idx = current_size - 1;
- while(idx != 0){
- int parentIdx = parentIndex(idx);
- if(!(less(nodes[parentIdx],nodes[idx]))){
- T temporary = nodes[parentIdx];
- nodes[parentIdx] = nodes[idx];
- nodes[idx] = temporary;
- idx = parentIdx;
- }else
- break;
- }
- return true;
- }
- template<class T, class Equal, class Less>
- T BHeap<T,Equal,Less>::pop(void)
- {
- if(empty())
- return T();
- T result = nodes[0];
- nodes[0] = nodes[current_size - 1];
- current_size--;
- if(current_size > 0){
- int idx = 0;
- while(true){
- int leftIdx = leftIndex(idx);
- int rightIdx = rightIndex(idx);
- int proot = 0;
- if(rightIdx >= current_size){
- if(leftIdx >= current_size)
- break;
- else
- proot = leftIdx;
- }else{
- if(less(nodes[leftIdx], nodes[rightIdx]))
- proot = leftIdx;
- else
- proot = rightIdx;
- }
- if(!less(nodes[idx],nodes[proot])){
- T temporary = nodes[proot];
- nodes[proot] = nodes[idx];
- nodes[idx] = temporary;
- idx = proot;
- }else
- break;
- }
- }
- return result;
- }
- template<class T, class Equal, class Less>
- void BHeap<T,Equal,Less>::shift(const int& idx)
- {
- int nidx = idx;
- while(nidx != 0){
- int parentIdx = parentIndex(nidx);
- if(!less(nodes[parentIdx],nodes[nidx])){
- T temporary = nodes[parentIdx];
- nodes[parentIdx] = nodes[nidx];
- nodes[nidx] = temporary;
- nidx = parentIdx;
- }else
- break;
- }
- }
- template<class T, class Equal, class Less>
- bool BHeap<T,Equal,Less>::realloc(const int& new_size)
- {
- if(new_size <= max_capcity || nodes == 0)
- return false;
- max_capcity = new_size;
- T* new_nodes = new T[max_capcity];
- if(current_size > 0)
- for(int i = 0; i < current_size; ++i)
- new_nodes[i] = nodes[i];
- delete []nodes;
- nodes = new_nodes;
- return true;
- }
- template<class T, class Equal, class Less>
- int BHeap<T,Equal,Less>::find(const T val)
- {
- for(int i = 0; i < current_size; ++i)
- if(cmp(nodes[i],val))
- return i;
- return -1;
- }
- template<class T, class Equal, class Less>
- const T& BHeap<T,Equal,Less>::operator[](const int& idx) const
- {
- return nodes[idx];
- }
- template<class T, class Equal, class Less>
- T& BHeap<T,Equal,Less>::operator[](const int& idx)
- {
- return nodes[idx];
- }
- }
- #endif