/**
* 优先队列
* 个人感觉,要掌握优先队列并不难,主要掌握以下要点就可以了。
* 1. 左右儿子跟父亲的关系。
* 设数组中位置i,左儿子位置[i*2],右儿子位置[i*2+1]。
* 2. 掌握上滤(percolate up)和下滤(percolate down)的原理。
* 下滤(percolate down)
* 把较小的儿子置入空穴,将空穴下滑一层,至到最后一层建立空穴。
* 上滤(percolate up)
* 为将一个元素X插入到堆中,在下一个空闲位置创建一个空穴,如果
* X放在空穴中而并不破坏堆序,那么插入完成。否则,把空穴的父结点
* 上的元素移到空穴中,这样,空穴就朝着根的方向上行一步。继续该过程
* 直到X能被放入到空穴为止。
*/
// 优先队列的类接口
template <typename Comparable>
class BinaryHeap
{
public:
explicit BinaryHeap(int capacity = 100);
explicit BinaryHeap(cosnt vector<Comparable& items);
bool isEmpty() const;
const Comparable & findMin() const;
void insert(const Comparable & x);
void deleteMin();
void deleteMin(Comparable & minItem);
void makeEmpty();
private:
int currentSize; // Number of elements in heap
vector<Comparable> array; // The heap array
void buildHeap();
void percolateDown(int hole);
};
// Insert item x, allowing duplicates.
void insert(const Comparable & x)
{
if(currentSize == array.size() - 1)
array.resize(array.size() * 2);
// Percolate up
int hole = ++currentSize;
for ( ; hole > 1 && x < array[hole / 2]; hole /= 2)
array[hole] = array[hole / 2];
array[hole] = x;
}
/**
* Remove the minimum item.
* throws UnderflowException if empty.
*/
void deleteMin()
{
if(isEmpty())
throw UnderflowException();
array[1] = array[currentSize--];
percolateDown(1);
}
/**
* Remove the minimum item and place it in minItem.
* Throws UnderflowException if empty.
*/
void deleteMin(Comparable & minItem)
{
if(isEmpty())
throw UnderflowException();
minItem = array[1];
array[1] = array[currentSize--];
percolateDown(1);
}
/**
* Internal method to percolate down in the heap.
* hole is the index at which the percolate begins.
*/
void percolateDown(int hole)
{
int child;
Comparable tmp = array[hold];
for ( ; hole * 2 <= currentSize; hold = child)
{
child = hold * 2;
if (child != currentSize && array[child + 1] < array[child])
child++;
if(array[child] < tmp)
array[hole] = array[child];
else
break;
}
array[hole] = tmp;
}
// buildHeap和构造函数
explicit BinaryHeap(const vector<Comparable> & item)
: array(items.size() + 10), currentSize(items.size())
{
for (int i = 0; i < items.size(); i++)
array[i + 1] = items[i];
buildHeap();
}
/**
* Establish heap order property from an arbitrary
* arrangement of items. Runs in linear time.
*/
void buildHeap()
{
for (int i = currentSize / 2; i > 0; i--)
percolateDown(i);
}