#ifndef COMPLETEBINARYHEAP_H_ #define COMPLETEBINARYHEAP_H_ #include "../chp2/Vector.h" #include "PriorityQueue.h" #define INHEAP(i) ((i >= 0) && (i < getSize())) #define PARENT(i) ((i-1) >> 1) #define LCHILD(i) ((i << 1) + 1) #define RCHILD(i) ((i << 1) + 2) #define HASPARENT(i) INHEAP(PARENT(i)) #define HASLCHILD(i) INHEAP(LCHILD(i)) #define HASRCHILD(i) INHEAP(RCHILD(i)) #define LASTINTERNAL PARENT(size() - 1) template class CBHeap: public Vector>, public PriorityQueue{ protected: //internal methods void percolate_down(int pos); void percolate_up(int pos); int proper_parent(int pos); public: //constructor CBHeap() = default; CBHeap(entry* src, int n); int size() { return getSize(); } bool empty(){ return size() == 0; } void insert(entry e); void insert(K key, V value) { insert(entry(key, value)); } entry getMax() { return _elem[0]; } entry delMax(); }; //internal methods template int CBHeap::proper_parent(int pos){ if (!HASLCHILD(pos)) return pos; if (!HASRCHILD(pos)) return get(pos) >= get(LCHILD(pos)) ? pos : LCHILD(pos); int proper = get(pos) >= get(LCHILD(pos)) ? pos : LCHILD(pos); return get(proper) >= get(RCHILD(pos)) ? proper : RCHILD(pos); } template void CBHeap::percolate_down(int pos){ entry tmp = get(pos); for(int p = proper_parent(pos); p != pos; p = proper_parent(pos)){ get(pos) = get(p); pos = p; get(pos) = tmp; } } template void CBHeap::percolate_up(int pos){ entry tmp = get(pos); while(HASPARENT(pos)){ if(get(PARENT(pos)) >= tmp) break; get(pos) = get(PARENT(pos)); pos = PARENT(pos); } get(pos) = tmp; } //public methods template CBHeap::CBHeap(entry* src, int n){ copyfrom(src, 0, n); for (int ix = LASTINTERNAL; ix >= 0; --ix) percolate_down(ix); } template void CBHeap::insert(entry e){ push_back(e); percolate_up(getSize() - 1); } template entry CBHeap::delMax(){ entry max = get(0); _elem[0] = _elem[_size-- - 1]; percolate_down(0); return max; } #endif