【堆】堆中的路径

【堆】堆中的路径

题目要求:

将一系列给定数字插入一个初始为空的小顶堆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 
#define MaxSize 10001 // 堆的空间(因为岗哨占一个空间,因此设定为10001) 
#define MinH -10001 // 设置一个比堆中任意元素都下的岗哨(最小堆就设置为最小)

void CreateHeap(int n); // 建堆 
void InsertHeap(int e); // 元素插入堆 

int minHeap[MaxSize],size; // 最小堆和堆的大小(堆中元素个数) 

int main()
{
	int N,M; // N:插入元素个数 M:打印路径条数
	int i,j,index;
	scanf("%d %d",&N,&M);
	CreateHeap(N); // 建立最小堆
	for(i = 0;i < M;i ++) {
		scanf("%d",&index);
		for(j = index;j > 1;j /= 2)
			printf("%d ",minHeap[j]);
		printf("%d\n",minHeap[j]);
	}	
} 

void CreateHeap(int n) // n是堆的元素个数 
{
	int i,el;
	size = 0; // 先建个空堆
	minHeap[0] = MinH; // 设置岗哨
	for(i = 0;i < n;i ++) {
		scanf("%d",&el); 
		InsertHeap(el);
	} 
}

/* 
【思路】
插入元素的位置起初为size + 1,但是为了保证是最小堆,要进行调整,调整的策略就是向上层(父结点)比较,如果上层元素
比该元素大就把上层元素换下来,逐层向上比较,直到不能满足父结点比插入元素大时,此时i指向的位置就是应该插入的位置 
*/ 
void InsertHeap(int e) // e是要插入堆中的元素 
{
	int i;
	for(i = ++ size;minHeap[i / 2] > e;i /= 2) {
		minHeap[i] = minHeap[i / 2]; // 只要父结点比要插入的元素大,就把父结点换下来 
	}
	minHeap[i] = e;  
}

你可能感兴趣的:(算法与数据结构,数据结构,算法)