6-8 Percolate Up and Down (20 point(s))
Write the routines to do a “percolate up” and a “percolate down” in a binary min-heap.
Format of functions: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;
};
Sample program of judge:#include
#include
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
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 */
Sample Input:9
1 10
1 5
1 2
0
1 9
1 1
1 4
0
0
Sample Output:2 1 4
Inside H: 5 10 9
这里最小端的插入是将树放在堆的最后一个位置,再进行向上调整操作,向上调整的过程是不断比较交换儿子与父亲的值。
删除最小值操作,是将最小值弹出,然后将最后一个元素放在最小值位置,再向下调整,向下调整的过程是不断比较父亲与儿子的值,这里左右儿子都要比较,如果发现小,就交换下去
完整代码#include
#include
typedef int ElementType;
#define MinData -1
#define MaxData 1000
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 PercolateUp(int p, PriorityQueue H)
{
int i = p;
if (i == 1)
return; // 如果插入的是第一个根节点,那么不用 PercolateUp操作
while (i != 1)
{
// 如果儿子比父亲小就交换,最小堆
if (H->Elements[i] < H->Elements[i / 2])
{
int temp = H->Elements[i];
H->Elements[i] = H->Elements[i / 2];
H->Elements[i / 2] = temp;
}
else
break;
i = i / 2;
}
}
void PercolateDown(int p, PriorityQueue H)
{
int i = p;
int t; // t记录左右儿子更小值得下标
while (2 * i <= H->Size)
{
if (H->Elements[i] > H->Elements[2 * i])
{
t = 2 * i;
}
else
{
t = i;
}
if (2 * i + 1 <= H->Size) // 判断右子数是否存在
{
if (H->Elements[t] > H->Elements[2 * i + 1])
{
t = i * 2 + 1;
}
}
if (t == i)
break;
else
{
int temp = H->Elements[i];
H->Elements[i] = H->Elements[t];
H->Elements[t] = temp;
i = t;
}
}
}
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_s("%d", &n);
H = Initialize(n);
for (i = 0; i
{
scanf_s("%d", &op);
switch (op)
{
case 1:
scanf_s("%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 */
PriorityQueue Initialize(int MaxElements)
{
PriorityQueue H = (PriorityQueue)malloc(sizeof(struct HeapStruct));
H->Elements = (ElementType*)malloc((MaxElements + 1) * sizeof(ElementType));
H->Capacity = MaxElements;
H->Size = 0;
H->Elements[0] = MaxData;
return H;
}