6-8 Percolate Up and Down (20 分)

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 <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 */

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
void PercolateUp( int p, PriorityQueue H ){
    int i=H->Size;
    int X=H->Elements[p];
    for (; H->Elements[i/2]>X; i/=2) {
        H->Elements[i]=H->Elements[i/2];
    }
    H->Elements[i]=X;
}

void PercolateDown( int p, PriorityQueue H ){
    int X=H->Elements[1];
    int Parent,Child;
    for (Parent=1; Parent*2<=H->Size; Parent=Child) {
        Child=Parent*2;
        if (Child!=H->Size&&H->Elements[Child]>H->Elements[Child+1]) {
            Child++;
        }
        if(X<=H->Elements[Child])
            break;
        else
            H->Elements[Parent]=H->Elements[Child];
    }
    H->Elements[Parent]=X;
}
### 回答1: 6-1中的percolate uppercolate down是指数据结构中的两种操作方式。percolate up是指将一个新元素插入到堆中,并将其上移,以满足堆的性质。percolate down是指将堆中的某个元素下移,以满足堆的性质。这两种操作在堆排序、优先队列等算法中经常用到。 ### 回答2: 6-1 percolate up and down是一种数据结构中常见的操作方式,也被称为上滤和下滤。这种操作可以应用于多种数据结构,如堆、树等。 在堆中,每个节点都有一个权值,而堆的性质是根节点的权值最大(或最小)。当一个节点的值发生变化时,为了保持堆的性质,需要对堆进行调整。如果节点的值变小了(也就是权值减小了)那么就需要进行上滤,也就是将这个节点和它的父节点进行比较,如果节点的值小于父节点的值,就需要交换它们的值,直到这个节点不再小于它的父节点或者成为了根节点为止。 另一方面,如果一个节点的值变大了(权值增大了),那么就需要进行下滤。也就是将这个节点和它的子节点进行比较,如果节点的值大于其子节点的值,就需要交换它们的值,直到这个节点不再大于它的子节点或者成为了叶节点为止。 在树中,上滤和下滤的操作也类似于堆。上滤可以应用于新增节点的情况,当有新的节点插入到树中时,需要保证该节点的值符合树的性质,也就是保证该节点比其父节点的值小(或者大,根据树的性质而定)。下滤则可以应用于删除节点的情况,当有节点被删除时,需要保证树的性质不被破坏,也就是保证由于删除节点而导致的某个节点不符合树的性质时需要进行下滤操作。 总之,上滤和下滤是一种对数据结构进行调整的操作方式,可以用于保持数据结构的性质,或者在数据结构中进行节点插入和删除。在实际应用中,上滤和下滤是非常常用的操作方式。 ### 回答3: 6-1 Percolate Up and Down 是指一种常见的二叉堆向上和向下调整的算法。它主要用在二叉堆中插入和删除节点的时候,保证二叉堆的性质不被破坏。 首先介绍一下二叉堆,二叉堆是一种特殊的完全二叉树,它为两种:最大堆和最小堆。最大堆的每一个节点的值都比它的左右子节点的值都要大,而最小堆则相反,每一个节点的值比它的左右子节点的值都要小。因此,在二叉堆中,根节点的值是最大值或最小值,而从根节点开始向下,每一层又按照相应的规则排序,可以用数组或树来实现。 我们用插入操作来说明 Percolate UpDown 算法。在 Max-Heap 中,插入一个节点会破坏堆的性质,因为插入后,可能会出现某个节点大于它的父节点的情况。这个时候,我们需要将这个节点向上调整,即向父节点进行比较、交换操作。具体步骤如下: 1. 将新节点插入到堆的末尾。 2. 与父节点比较:如果新节点的值大于其父节点的值,就交换它们的位置。 3. 重复上述步骤,直到新节点大于其父节点或达到根节点。 这样,就可以确保新节点插入后仍然是一个 Max-Heap。这种向上调整的过程就是 Percolate Up。 接下来是删除操作,同样的,删除某个节点也会破坏堆的性质,因为删除节点后,在剩余的节点中可能会出现某个节点小于它的子节点。删除操作需要对堆进行向下调整,即从根节点开始,将最后一个节点放到根节点位置,然后按照从根节点向下的方式进行比较、交换操作,确保堆的性质不被破坏。具体步骤如下: 1. 将堆的根节点删除并保存到临时变量中。 2. 将堆的最后一个节点移到根节点位置。 3. 与子节点比较:如果根节点的值小于其中一个子节点的值,就将它与该子节点交换位置。 4. 重复上述步骤,直到没有子节点或根节点比它的子节点大。 这样,就可以确保删除节点后仍然是一个 Max-Heap。这种向下调整的过程就是 Percolate Down。 总之,Percolate UpDown 算法是二叉堆维护性质的重要算法,可以保证堆的插入、删除等操作后仍然是一个有序的堆。虽然以上讨论的是 Max-Heap,但 Min-Heap 的操作原理类似,只是方向相反。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值