将一系列给定数字插入一个初始为空的小顶堆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(" "); 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 }