7-5 堆中的路径(25 分)

将一系列给定数字插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。

输入格式:

每组测试第1行包含2个正整数N和M(≤),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。最后一行给出M个下标。

输出格式:

对输入中给出的每个下标i,在一行中输出从H[i]到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。

输入样例:

5 3
46 23 26 24 10
5 4 3

输出样例:

24 23 10
46 23 10
26 10


解题思路:1.做这道题首先要知道堆的特点:
堆是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于(或不小于)其左子节点和右子节点的值。
最大堆和最小堆是二叉堆的两种形式。
最大堆:根结点的键值是所有堆结点键值中最大者。
最小堆:根结点的键值是所有堆结点键值中最小者。
         2.那既然它是完全二叉树。那么一个结点下标为 i ,它的左孩子的下标为2i,右孩子的下标为2i+1,
父结点的下标为 i/2

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 
 4 #define max 1005
 5 #define min -10001
 6 
 7 void Create();
 8 void Insert( int temp);
 9 int h[max],size;
10 
11 int main()
12 {
13     int n,m;
14     int temp;
15     int i,j;
16 
17     scanf("%d %d",&n,&m);
18     Create();
19     for( i=0; i<n; i++){
20         scanf("%d",&temp);
21         Insert(temp);
22     }
23 
24     for( i=0; i<m; i++){
25         scanf("%d",&j);
26         printf("%d",h[j]);
27         while( j>1 ){
28             j /= 2;
29             printf(" %d",h[j]);
30         }
31         printf("\n");
32     }
33     return 0;
34 }
35 
36 void Create()
37 {
38     //初始化堆
39     size = 0;
40     h[0] = min;   //0位置不存数据,设置岗哨
41 }
42 
43 void Insert( int temp)
44 {
45     //插入结点形成小顶堆
46     int i;
47 
48     for( i=++size; h[i/2]>temp;i/=2){
49         //小顶堆,如果父节点大于插入结点则二者交换
50         h[i] = h[i/2];
51     }
52     h[i] =temp;
53 }
 
posted @ 2018-01-23 10:04  yuxiaoba  阅读(1594)  评论(0编辑  收藏  举报