1. 程式人生 > >PTA || 05-樹7 堆中的路徑

PTA || 05-樹7 堆中的路徑

將一系列給定數字插入一個初始為空的小頂堆H[]。隨後對任意給定的下標i,列印從H[i]到根結點的路徑。

輸入格式:

每組測試第1行包含2個正整數NNNMMM(≤1000\le 10001000),分別是插入元素的個數、以及需要列印的路徑條數。下一行給出區間[-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;
}