#include <stdio.h>
int CurrSize,MaxSize; //以下均假设数组第0个元素不使用
--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
插入:先插到最后面,然后循环地与父节点比较,在这个过程中
把元素一层层下移,直到找到合适的位置插入
--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
void HeapInsert(int h[],int x)
{
int i;
if(CurrSize == MaxSize) { printf("No Space!"); return; }
for(i=CurrSize+1; i!=1 && x>h[i/2]; i/=2)
h[i] = h[i/2]; //父节点下移
h[i] = x; //插入
CurrSize++;
}
--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
删除:删除根节点,然后抽出最后一个节点,
从根位置开始往下找合适的位置插入
--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
int HeapDelete(int h[])
{
int x = h[1]; //最大元素,即根
//-------------重构堆---------------
int y = h[CurrSize--]; //最后一个元素
int i=1/*当前节点*/,pi=2/*i的孩子*/;
while(pi <= CurrSize)
{
if(pi < CurrSize && h[pi] < h[pi+1])
pi++; //若存在右孩子且右孩子较大,则pi指向右孩子
//此时pi已指向i的孩子中较大者
if(y >= h[pi]) break; //y可插入h[i]
h[i] = h[pi]; //不可插入则上移较大孩子
i = pi; pi = pi*2; //继续往下做比较
}
h[i] = y; //插入
return x; //返回删除的元素
}
--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --
初始化:从最后一个有孩子的节点开始一直到根,对每一个有孩子的节点,
都在以其为根的子树中寻找合适的位置插入,过程类似于删除
--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --
void HeapInit(int h[],int cs,int ms)
{
int i,y,pi;
CurrSize = cs; MaxSize = ms;
for(i = CurrSize/2; i >= 1; i--)
{
y = h[i]; //子树的根
pi = 2*i; //其左孩子
while(pi <= CurrSize) //一直往下寻找合适的位置
{
if(pi < CurrSize && h[pi] < h[pi+1])
pi++; //若存在右孩子且右孩子较大,则pi指向右孩子
//此时pi已指向i的孩子中较大者
if(y >= h[pi]) break; //y可插入h[i]
h[pi/2] = h[pi]; //不可插入则上移较大孩子
pi = pi*2; //继续往下做比较
}
h[pi/2] = y; //插入
}
}
--- --- --- --- --- --- --- 调 用 --- --- --- --- --- --- ---
void main()
{
int t,a[11] = {0,5,2,7,3,9,1,4,8};
HeapInit(a,8,10); //初始化
HeapInsert(a,6); //插入
for(i=1;i<=9;i++) //堆排序
printf(" %d ",HeapDelete(a));
}