Write the routines to do a “percolate up” and a “percolate down” in a binary min-heap.
函数接口定义:
void PercolateUp( int p, PriorityQueue H );
void PercolateDown( int p, PriorityQueue H );
where int p is the position of the element, and PriorityQueue is defined as the following:
typedef struct HeapStruct *PriorityQueue;
struct HeapStruct {
ElementType *Elements;
int Capacity;
int Size;
};
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;
#define MinData -1
typedef struct HeapStruct *PriorityQueue;
struct HeapStruct {
ElementType *Elements;
int Capacity;
int Size;
};
PriorityQueue Initialize( int MaxElements ); /* details omitted */
void PercolateUp( int p, PriorityQueue H );
void PercolateDown( int p, PriorityQueue H );
void Insert( ElementType X, PriorityQueue H )
{
int p = ++H->Size;
H->Elements[p] = X;
PercolateUp( p, H );
}
ElementType DeleteMin( PriorityQueue H )
{
ElementType MinElement;
MinElement = H->Elements[1];
H->Elements[1] = H->Elements[H->Size--];
PercolateDown( 1, H );
return MinElement;
}
int main()
{
int n, i, op, X;
PriorityQueue H;
scanf("%d", &n);
H = Initialize(n);
for ( i=0; i<n; i++ ) {
scanf("%d", &op);
switch( op ) {
case 1:
scanf("%d", &X);
Insert(X, H);
break;
case 0:
printf("%d ", DeleteMin(H));
break;
}
}
printf("\nInside H:");
for ( i=1; i<=H->Size; i++ )
printf(" %d", H->Elements[i]);
return 0;
}
/* Your function will be put here */
输入样例:
9
1 10
1 5
1 2
0
1 9
1 1
1 4
0
0
输出样例:
2 1 4
Inside H: 5 10 9
代码:
/*堆是用数组储存,从下标为1开始储存,若父结点下标为i,左孩子下标为2i,右孩子下标为(2i+1)*/
//该题为最小堆
//最小堆的插入:把要插入的结点放在最末尾,然后上调至正确位置
void PercolateUp( int p, PriorityQueue H )
{
int i=p/2;//i为父结点
for(;H->Elements[i]>H->Elements[p];i=i/2)//如果父结点的值>子结点,继续循环
{
//交换父结点和子结点的值
int temp=H->Elements[i];
H->Elements[i]=H->Elements[p];
H->Elements[p]=temp;
p=i;
}
}
//最小堆的删除:把根结点保留,最小堆的删除是删除最小元素,即删除根节点。把最末尾的元素代替根结点,然后下调至正确位置
void PercolateDown( int p, PriorityQueue H )
{
int c;//子结点
for(;p*2<=H->Size;p=c)//循环条件为父结点下标<=堆的元素个数
{
c=p*2;//一般子结点默认为左孩子
if((c+1!=H->Size)&&(H->Elements[c+1]<H->Elements[c]))//判断左右孩子中谁小且右孩子存在
c++;
if(H->Elements[p]<=H->Elements[c])//一直到调整至父结点小于子结点为止
break;
else//父结点大于子结点,父子结点交换数值
{
int t=H->Elements[p];
H->Elements[p]=H->Elements[c];
H->Elements[c]=t;
}
}
}