建立堆-05-树7 堆中的路径

  • 题目
    05-树7 堆中的路径 (25分)
  • 分析
    这道题考察建立最小堆的基本操作。
    首先堆是一种优先队列,可以用完全二叉树的方式来表示,从根结点到任意结点路径上都是有序的。完全可以用数组来存储。
    有一个技巧点是数组的第一个元素可以作为“哨兵”,存放最小的一个数字(最小堆),它比堆中的任意一个元素都要小,这样方便后序的插入、删除等操作。
    我们知道,有两种建立堆的方式:
    1. 将一个个元素插入初始为空的堆中,这样每次插入的时间复杂度为O(logN),N个元素都插入之后建好堆,时间复杂度为O(N*logN)。
      //但是这道题只能这样做,因为题中明确说明:
      * 将一系列给定数字插入一个初始为空的小顶堆H[]*
    2. 将N个结点先顺序存入数组,使之符合完全二叉树的结构特性;然后依次从各个结点(从N/2 到 1位置上的结点)开始调整,使之子树成为最小堆。那么最后调整位置为1的结点后,整个树就是一个最小堆了。这样的时间复杂度为O(N)
  • 我的代码一(方法一,java语言描述)
package pat;
import java.util.Scanner;
public class CreateHeap {
    static int capicity = 1001;
    static int minNum = -10001;
    static int[] minHeap = new int[capicity];
    static{
        minHeap[0] = minNum;
    }

    static void insert(int x,int index){
        while(x < minHeap[index/2]){
            minHeap[index] = minHeap[index/2];
            index /= 2;
        }
        minHeap[index] = x;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n,m,x;
        n = in.nextInt();
        m = in.nextInt();
        for(int i=1; i<=n; i++){
            x = in.nextInt();
            CreateHeap.insert(x, i);
        }

        int pos = 1;
        for(int i=1; i<=m; i++){
            pos = in.nextInt();
            while(pos != 0){
                System.out.print(minHeap[pos]);
                if(pos != 1){
                    System.out.print(" ");
                }
                pos /= 2;
            }
            System.out.println();
        }

    }

}

结果因为java效率低,超时了。。
- 我的代码二(方法一 C语言版)

#include
#include

#define capicity 1001
#define minNum -10001

int minHeap[capicity];

void insetHeap(int x,int index)
{
    while(x < minHeap[index/2])
    {
        minHeap[index] = minHeap[index/2];
        index /= 2;
    }
    minHeap[index] = x;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);

    minHeap[0] = minNum;
    int i,x;
    for(i=1; i<=n; i++)
    {
        scanf("%d",&x);
        insetHeap(x,i);
    }

    int pos;
    for(i=1; i<=m; i++)
    {
        scanf("%d",&pos);
        while(pos){
            printf("%d",minHeap[pos]);
            if(pos != 1)    printf(" ");
            pos /= 2;
        }
        printf("\n");
    }

    return 0;
} 

通过了

下面给出构建最大堆的函数代码,看懂思想就很容易写出来。不过要注意的是该题不能运用这个方法,因为这样构造出来的堆和一个个插入构造出来的堆结构不一定相同,那么输出的顺序就不同。

/*----------- 建造最大堆 -----------*/
void PercDown( MaxHeap H, int p )
{ /* 下滤:将H中以H->Data[p]为根的子堆调整为最大堆 */
    int Parent, Child;
    ElementType X;

    X = H->Data[p]; /* 取出根结点存放的值 */
    for( Parent=p; Parent*2<=H->Size; Parent=Child ) {
        Child = Parent * 2;
        if( (Child!=H->Size) && (H->Data[Child]Data[Child+1]) )
            Child++;  /* Child指向左右子结点的较大者 */
        if( X >= H->Data[Child] ) break; /* 找到了合适位置 */
        else  /* 下滤X */
            H->Data[Parent] = H->Data[Child];
    }
    H->Data[Parent] = X;
}

你可能感兴趣的:(数据结构与算法)