写个简单的堆,数组版的
C++的优先队列好像就是堆吧
Source code
/* 定义堆的最大的结点数 */
#define SIZE 1000
/* 用数组装堆,size表示目前的结点数 */
int heap[SIZE], size;
/* 初始化堆 */
void init()
{
size = 0;
}
/* 比较函数,决定是小顶还是大顶 */
int cmp(int a, int b)
{
/* '<'是小顶,'>'是大顶 */
return a < b;
}
/* 取堆顶 */
int pop()
{
/* ans是最终要返回的结果,即堆顶 */
int ans = heap[0];
/* x是最末尾的元素,在维护的时候想尽量往顶靠 */
int x = heap[--size];
/* pos表示理想的放x的位置,初始化为堆顶位置 */
int pos = 0;
/* 只要还有左儿子,就还有更新的可能 */
while(pos * 2 + 1 < size)
{
int ch = pos * 2 + 1;
/*
** ch + 1 是右儿子,如果有,要考虑下它的情况
** 小顶堆为例
** 因为堆顶是放最小元素的
** 要从左右儿子中找较小的一个
** 让它和想上顶的 x 比较
** 只有较小的那个才能上位
*/
if(ch + 1 < size && cmp(heap[ch + 1], heap[ch]) )
++ch;
/*
** 小儿子与 x 的竞争
** 因为pos的位置是用来放x的,x想上顶而pos又是从上往下找
** 如果是x比较小,那放x的最佳位置就找到了,就break
*/
if( cmp(x, heap[ch]) )
break;
/*
** 如果x是比较大的,那就要再往下找
** 先把小儿子的值往上提
** 再考虑原小儿子的位置是否合适
*/
heap[pos] = heap[ch];
pos = ch;
}
heap[pos] = x;
return ans;
}
/* 进堆 */
void push(int in)
{
/*
** pos是目前安排的放in的位置
** 先把新来的安排在最后
** 然后再向上考虑换位
*/
int pos = size++;
while(pos > 0)
{
/* 父结点的位置是可能还位的位置 */
int fa = (pos - 1) / 2;
/*
** 如果in并没有比fa位置的元素小
** 那就放在当前安排的pos的位置
*/
if( !cmp(in, heap[fa]) ) // 或:cmp(heap[fa], in)
break;
/*
** 否则把fa位置的元素放下来
** 再考虑能否更上一层
*/
heap[pos] = heap[fa];
pos = fa;
}
heap[pos] = in;
}