最大堆的插入
步骤:
1.将新插入元素放在size+1的位置
2.向上过滤结点使之满足最大堆的特点
最大堆的删除
基本概念:对于一个完全二叉树,结点序号为i的左孩子是2i,右孩子是2i+1。
步骤
1.堆是否为空(为空则无法删除)
2.若不为空,取出根结点的最大元素
3.将数组下标最大的一个元素提出来,放在根结点位置
4.从上到下过滤结点
heap->Data[heap->size]待比较元素
过滤结点的具体操作
4.1 parent*2<=heap->size//判别有没有左孩子
4.2 没有左孩子时,一定也没有右孩子,即为完全二叉树最下面一层,位置已找到
4.3 若有左孩子,并且child!=heap->size(判断有没有右孩子)时(即把上面判别有没有左孩子的条件中等号去掉),说明既有左孩子也有右孩子
4.4在有左右孩子时,比较两个孩子大小,如果右孩子大,那么child++,即为选择右孩子的路径向下过滤
代码
#include<stdio.h>
#include<malloc.h>
typedef struct heap{
int *Data;
int size;//当前数量
int maxsize;//最大数量
}*Maxheap;
int Maxterm;
Maxheap gen(int Maxsize);
Maxheap insert(int X,Maxheap heap);
Maxheap delete();
Maxheap gen(int Maxsize)
{
Maxheap heap;
heap=(Maxheap)malloc(sizeof(struct heap));
heap->Data=(int *)malloc(sizeof(int)*(Maxsize+1));
heap->maxsize=Maxsize;
heap->size=0;
heap->Data[0]=100000;
return heap;
}
Maxheap insert (int X,Maxheap heap)
{
if(heap->maxsize==heap->size)//堆已满
return heap;
else
{
int temp=(heap->size+1);
while(heap->Data[temp/2]<X)
{
heap->Data[temp]=heap->Data[temp/2];
temp=temp/2;
}
heap->Data[temp]=X;
return heap;
}
}
Maxheap delete(Maxheap heap)
{
if(heap->size==0)//最大堆为空
return heap;
else
{
Maxterm=heap->Data[1];
int temp=heap->Data[heap->size];
heap->size--;
heap->Data[1]==heap->Data[heap->size];
int parent=1;
int child;
int idx=heap->Data[heap->size];
for(parent=1;parent*2<=heap->size;parent=child)//有左孩子
{
child = parent*2;
if((child!=heap->size)&&(heap->Data[child]<heap->Data[child+1]))//有右孩子且右孩子大于左孩子
child++;//选这条路径
if((temp>=heap->Data[child]))//已经找到位置,比左右孩子中最大的一个元素还大
break;
else//还没有找到,继续向下寻找
heap->Data[parent]=heap->Data[child];
}
heap->Data[parent]=temp;//将待比较元素放在合适的位置
return heap;
}
}
**建立最大堆**
类似于最大堆的删除,从最后一个父结点到第一个结点,依次向下过滤,使其满足最大堆的特性。
```c
/*----------- 建造最大堆 -----------*/
void PercDown( Maxheap H, int p )
{ /* 下滤:将H中以H->Data[p]为根的子堆调整为最大堆 */
int Parent, Child;
int X;
X = H->Data[p]; /* 取出根结点存放的值 */
for( Parent=p; Parent*2<=H->size; Parent=Child ) {
Child = Parent * 2;
if( (Child!=H->size) && (H->Data[Child]<H->Data[Child+1]) )
Child++; /* Child指向左右子结点的较大者 */
if( X >= H->Data[Child] ) break; /* 找到了合适位置 */
else /* 下滤X */
H->Data[Parent] = H->Data[Child];
}
H->Data[Parent] = X;
}
void BuildHeap( Maxheap H )
{ /* 调整H->Data[]中的元素,使满足最大堆的有序性 */
/* 这里假设所有H->Size个元素已经存在H->Data[]中 */
int i;
/* 从最后一个结点的父节点开始,到根结点1 */
for( i = H->size/2; i>0; i-- )
PercDown( H, i );
}