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

来源:互联网 发布:网页游戏如何修改数据 编辑:程序博客网 时间:2024/06/05 02:27
  • 题目
    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<stdio.h>#include<stdlib.h>#define capicity 1001#define minNum -10001int 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]<H->Data[Child+1]) )            Child++;  /* Child指向左右子结点的较大者 */        if( X >= H->Data[Child] ) break; /* 找到了合适位置 */        else  /* 下滤X */            H->Data[Parent] = H->Data[Child];    }    H->Data[Parent] = X;}
0 0
原创粉丝点击