堆的概念及结构
如果有一个数据集合K ,把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:ki<=k2i+1且ki<=k2i+2(或满足ki>=k2i+1且ki>=k2i+2)其中i=0,1,2,…,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
堆的实现
堆的向下调整算法
现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整 成一个小堆。向下调整算法有一个前提:左右子树必须是一个堆,才能调整。例:现输入一个数组array
array的逻辑结构如图所示:以27为根节点的左右子树,都满足小堆的性质,只有根节点不满足,因此只要将根节点向下调整到合适位置就可以得到堆。
向下调整:
向下调整的思想:
1.从根节点开始,选择左右子节点中较小(较大)的子节点。
2:让选出的子节点与其父节点进行比较:若小(大)的子节点比父节点还小(大),则交换位置。直到调整到叶节点为止。若小(大)的子节点比父节点还大(小)则调整完成。
代码如下:
//交换函数
void Swap(int*p1,int*p2)
{
int tmp=*p1;
*p1=*p2;
*p2=tmp;
}
void AdjustDown(int*a,int n,int parent)
{
int child = parent*2+1;
while(child < n)
{
if(child+1<n && a[child+1]<a[child])
{
child++;
}
if(a[child]<a[parent])
{
Swap(&a[parent],&a[child]);
parent=child;
child=parent*2+1;
}
else
{
break;
}
}
}
堆的向上调整算法
当在一个堆的末尾插入数据时,为了保证其仍为堆,可能会需要进行调整数据的位置,这个时候可以使用向上调整算法。
向上调整的思想:
1.将子节点与其父节点进行比较。
2.若子节点的值比父节点的值小(大),交换父子节点的值,再以交换后的父节点为子节点重复进行该过程,直至堆的根节点,调整成为一个小(大)堆。
代码如下:
//交换函数
void Swap(int*p1,int*p2)
{
int tmp=*p1;
*p1=*p2;
*p2=tmp;
}
void AjustUp(int*a , int child)
{
int parent=(child-1)/2;
while(child>0)
{
if(a[child]<a[parent])
{
Swap(&a[child],&a[parent]);
child=parent;
parent=(child-1)/2;
}
else
{
break;
}
}
}