1. 程式人生 > >凜冬之翼---堆的建立

凜冬之翼---堆的建立

題目:
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; }