樹7 堆中的路徑

AllenRicard發表於2018-10-10

將一系列給定數字插入一個初始為空的小頂堆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

答案如下

#include <stdio.h>
#include<stdlib.h>
typedef struct HNode *Heap; /* 堆的型別定義 */
struct HNode {
	int *Data; /* 儲存元素的陣列 */
	int Size;          /* 堆中當前元素個數 */
	int Capacity;      /* 堆的最大容量 */
};
typedef Heap MaxHeap; /* 最大堆 */
typedef Heap MinHeap; /* 最小堆 */

#define MINDATA -100001  /* 該值應根據具體情況定義為大於堆中所有可能元素的值 */

MinHeap CreateHeap( int MaxSize )
{ /* 建立容量為MaxSize的空的最大堆 */

	MinHeap H = (MinHeap)malloc(sizeof(struct HNode));
	H->Data = (int *)malloc((MaxSize+1)*sizeof(int));
	H->Size = 0;
	H->Capacity = MaxSize;
	H->Data[0] = MINDATA; /* 定義"哨兵"為大於堆中所有可能元素的值*/

	return H;
}

bool IsFull( MinHeap H )
{
	return (H->Size == H->Capacity);
}

bool Insert( MinHeap H, int X )
{ /* 將元素X插入最小堆H,其中H->Data[0]已經定義為哨兵 */
	int i;

	if ( IsFull(H) ) { 
		printf("最小堆已滿");
		return false;
	}
	i = ++H->Size; /* i指向插入後堆中的最後一個元素的位置 */
	for ( ; H->Data[i/2] > X; i/=2 )
		H->Data[i] = H->Data[i/2]; /* 上濾X */
	H->Data[i] = X; /* 將X插入 */
	return true;
}
void PathTraverse(Heap h,int indix){
	if (indix<=h->Size&&indix>0){
		printf("%d",h->Data[indix]);
		indix/=2;
		for (;indix>0;indix/=2)
			printf(" %d",h->Data[indix]);
	}
	else
		printf("請輸入正確的下標");
}
int main(){
	int N,M;
	scanf("%d %d",&N,&M);
	Heap H=CreateHeap(N+1);
	int i=1,data;
	for (;i<=N;i++){
		H->Size=i-1;
		scanf("%d",&data);
		Insert(H,data);
	}
	int indix;
	for (i=0;i<M;i++)
	{
		scanf("%d",&indix);
		PathTraverse(H,indix);
		printf("\n");
	}
	return 0;
}

 

相關文章