完全二叉树
1.完全二叉树的最小堆中父节点都比左儿子节点和右儿子节点要小,
若某节点的编号为i,则他的父节点编号为i/2(取整),他的左儿子节点编号为i*2,右儿子节点编号为i*2+1
2.最小堆的向下调整
若将编号为i的节点替换,则为了满足最小堆特点,调整函数
void siftdown(int i)
{
int t, flag=0 ;//flag用来判断是否需要继续向下调整
while(i*2<=n&&flag==0)
{
//判断他与左儿子节点的大小关系
if(h[i]>h[i*2])
t=i*2;
else
t=i;
//如果有右儿子节点,则与右儿子节点比较
if(i*2+1<=n)
{
if(h[t]>h[i*2+1])
t=i*2+1;
//如果发现最小的节点不是自己 ,说明子节点有比父节点更小的
}
if(t!=i)
{
交换h[t]和和h[i]的值
i=t;
}
else
{ flag=1;
}
}
}
2.向上调整
主体思路:
void siftup(int i)//传入一个需要向上调整的节点编号
{
flag=0;
如果i=1,表示是堆顶,直接返回结束return
如果i!=1,
while(i!=1&&flag==0)
则判断i与父节点i/2的大小,如果h[i]<h[i/2],则交换h[i]与h[i/2]的值,并令i=i/2,进行下一次循环,反之,表示不需要再做调整,退出循环)
}
经过该函数,便可实现最小堆的维护
3.最小堆的建立
1)
n=0;
for(i:1~m)
{
n++;
h[n]=输入的值;
siftup(n);
}
2)
for(i=n/2;i>=1;i++)
siftdown(i);