最小堆的路径

本题完成最小堆的建立

将一系列给定数字插入一个初始为空的小顶堆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
题目的
题目的最小对堆建立后变成上述的样子,因此查询5,返回的路径是24(下标为5),23,10

输出样例:

24 23 10
46 23 10
26 10

其中关键点在于:

  • 最小堆使用数组完成比较好,从尾部插入,如果其父节点比插入的元素大,父节点元素下移动
  • 一个下标 i 的 i/2 一定是其父节点的下标,这样从最下端插入元素时可以很快得跟父节点进行比较
  • 堆的0下标元素需要设置一个岗哨元素,取堆元素可能取到的最小值,这样不会数组越界

代码如下:

#include<stdio.h>
#include<stdlib.h>

#define maxsize 1001
#define minelement -10001

int heap[maxsize], size;

void makeheap(int n);//建立最小堆
void print(int i);//打印i节点的位置的路径
void insert(int v);//向堆中插入元素

int main()
{
	int n, m;
	scanf("%d %d", &n, &m);
	makeheap(n);
	while (m)
	{
		int tep;
		scanf("%d", &tep);
		print(tep);
		m--;
	}
	return 0;
}

void makeheap(int n)
{
	size = 0;
	heap[0] = minelement;//在零下标的位置处设置岗哨元素,保证最小的插在1的位置
	int i;
	for (i = 0; i < n; i++)
	{
		int tep;
		scanf("%d", &tep);
		insert(tep);
	}
	return;
}

void insert(int v)//向堆中插入元素
{
	if (size == maxsize - 1)return;//如果size超过数组的最大值,不能插入
	int i;
	for (i = ++size; heap[i / 2] > v; i /= 2)//插入前堆的size加1,同时i从最后这个元素开始插入,如果其父节点比插入的节点小,退出循环
		heap[i] = heap[i / 2];//没有退出循环表示父节点比要插入的大,因此其父节点下移动
	heap[i] = v;
	return;
}

void print(int i)//打印i节点的位置的路径
{
	printf("%d", heap[i]);
	i /= 2;
	for (; i >= 1; i /= 2)
		printf(" %d", heap[i]);
	printf("\n");
	return;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值