PTA || 05-樹7 堆中的路徑
阿新 • • 發佈:2018-12-18
將一系列給定數字插入一個初始為空的小頂堆H[]
。隨後對任意給定的下標i
,列印從H[i]
到根結點的路徑。
輸入格式:
每組測試第1行包含2個正整數NNN和MMM(≤1000\le 1000≤1000),分別是插入元素的個數、以及需要列印的路徑條數。下一行給出區間[-10000, 10000]內的NNN個要被插入一個初始為空的小頂堆的整數。最後一行給出MMM個下標。
輸出格式:
對輸入中給出的每個下標i
,在一行中輸出從H[i]
到根結點的路徑上的資料。數字間以1個空格分隔,行末不得有多餘空格。
輸入樣例:
5 3
46 23 26 24 10
5 4 3
輸出樣例:
24 23 10
46 23 10
26 10
參考程式碼1(順序插入再調整
#include <stdio.h> #include <stdlib.h> #define ElementType int #define MINDATA -10000 //小頂堆型別定義 typedef struct HNode *Heap; struct HNode { ElementType *Data;//儲存元素的陣列 int Size;//堆中當前元素的個數 int Capacity;//堆的最大容量 }; typedef Heap MinHeap; MinHeap CreatHeap(int MaxSize);//建立容量為MaxSize的空的小頂堆 //MinHeap Insert(MinHeap H, ElementType X);//按輸入順序插入元素,不是按小頂堆的順序插入 void BuildHeap(MinHeap H);//建立小頂堆 void PercDown(MinHeap H, int p);//將現有的堆調整為小頂堆,將H中以H->Data[p]為根的子堆調整為小頂堆 bool IsFull(MinHeap H);//判斷小頂堆H是否已滿,滿則返回true,不滿則返回false //整體程式框架 int main() { MinHeap H; int N, M, i, j; ElementType x; scanf("%d %d\n", &N, &M); H = CreatHeap(N); int a[M] = {0,}; while (!IsFull(H)){ scanf("%d", &x); H->Size ++; H->Data[H->Size] = x; } BuildHeap(H); for (i=0; i<M; i++) scanf("%d", &a[i]); for (i=0; i<M; i++){ for (j=a[i]; j>0; j/=2){ printf("%d", H->Data[j]); if (j != 1) printf(" "); else printf("\n"); } } return 0; } MinHeap CreatHeap(int MaxSize) //建立容量為MaxSize的空的小頂堆 { MinHeap H = (MinHeap)malloc(sizeof(struct HNode)); H->Data = (ElementType *)malloc((MaxSize + 1)*sizeof(ElementType)); H->Size = 0; H->Capacity = MaxSize; H->Data[0] = MINDATA;//定義“哨兵”為小頂堆中所有可能的最小值 return H; } bool IsFull(MinHeap H) //判斷小頂堆H是否已滿 { return (H->Size == H->Capacity ); } void BuildHeap(MinHeap H) //建立小頂堆 /*********************************************************** 1.建立的第一步,是按輸入順序插入元素,不是按小頂堆的順序插入 2.從最後一個父節點開始,將現有的堆調整為小頂堆 ***********************************************************/ { int i; for (i = H->Size/2 ; i>0; i--){ PercDown(H, i); } } void PercDown(MinHeap H, int p) //將現有的堆調整為小頂堆,將H中以H->Data[p]為根的子堆調整為小頂堆 { int Parent, Child; ElementType X; X = H->Data[p]; for (Parent = p; Parent*2<=H->Size ;Parent = Child ){ Child = Parent*2; if ((Child != H->Size ) && (H->Data[Child] > H->Data[Child+1])) Child++; if (X > H->Data[Child]) H->Data[Parent] = H->Data[Child]; else break; } H->Data[Parent] = X; }
參考程式碼2(逐個插入建小頂堆)
#include <stdio.h> #include <stdlib.h> #define ElementType int #define MINDATA -10000 //小頂堆型別定義 typedef struct HNode *Heap; struct HNode { ElementType *Data;//儲存元素的陣列 int Size;//堆中當前元素的個數 int Capacity;//堆的最大容量 }; typedef Heap MinHeap; MinHeap CreateHeap(int MaxSize); void Insert(MinHeap H, ElementType X); //主體程式框架 int main() { MinHeap H; ElementType x; int N, M, i, j; scanf("%d %d\n", &N, &M); H = CreateHeap(N); for (i = 0; i < N; i++){ scanf("%d", &x); Insert(H, x); } int a[M] = {0,}; for (i = 0; i<M; i++) scanf("%d", &a[i]); for (i = 0; i<M; i++ ){ for (j = a[i]; j>0; j/=2){ printf("%d", H->Data[j]); if (j != 1) printf(" "); else printf("\n"); } } return 0; } MinHeap CreateHeap(int MaxSize) { MinHeap H = (MinHeap)malloc(sizeof(struct HNode)); H->Data = (ElementType *)malloc((MaxSize + 1)*sizeof(ElementType)); H->Size = 0; H->Capacity = MaxSize; H->Data[0] = MINDATA; return H; } void Insert(MinHeap H, ElementType X) { int i; for (i = ++(H->Size); H->Data[i/2] > X;i/=2 ) H->Data[i] = H->Data[i/2]; H->Data[i] = X; }