凜冬之翼---堆的建立
阿新 • • 發佈:2018-11-13
題目:
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;
}