凛冬之翼---堆的建立
程序员文章站
2024-03-15 21:52:12
...
题目:
05-树7 堆中的路径 (25 分)
将一系列给定数字插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。
输入格式:
每组测试第1行包含2个正整数N和M(≤1000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-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.在堆中插入一个元素的方法是先将这个元素放到堆的size++为即最后一位,然后根据H[i/2]是H[i]的父亲的结论,将比要插入元素大的节点拉下来,完成循环后,最后确定的那个i就是元素x该去的地方。
遇到的问题:
1.在遇到while 函数的时候要特别小心作为变量的j要求变,不要最后出不来循环。
2.i/=2表示i=i/2; i=++size 表示i=size+1。
代码:
#include<stdio.h>
#include<stdlib.h>
#define Max 10001
#define Min -10001
int H[Max],size;
void Create(){ //this is a function to create a new heap
H[0]=Min;
size=0;
}
void Insert(int x){
int i;
for(i=++size;H[i/2]>x;i/=2){
H[i]=H[i/2]; //let the father be the son once father is bigger than son
}
H[i]=x; //finally we find the i the right place to be set x
// printf("fine ");
}
int main(){
int n,m,x,i,j;
scanf("%d %d",&n,&m);
Create(); // a blank heap
for(i=0;i<n;i++){ //create a new heap
scanf("%d",&x);
Insert(x);
// printf("ok");
}
// printf(" here");
for(i=0;i<m;i++){
scanf("%d",&j); //konw the number
printf("%d",H[j]);
while(j>1){
j/=2;
printf(" %d",H[j]);
}
printf("\n");
}
return 0;
}
上一篇: 【数据结构】--》堆的应用
下一篇: for循环打印一个九九乘法表
推荐阅读