堆中的路径(小顶堆的建立以及堆排序)
2021-02-12 07:19
标签:存储 heap 路径 show temp 最小 code 建堆 说明 推排序中的小顶堆的建立,需要注意的是,哪怕是相同的数,不同的插入顺序最终建立堆都不一样。 将一系列给定数字插入一个初始为空的小顶堆 组测试第1行包含2个正整数N和M(≤1000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。最后一行给出M个下标。 对输入中给出的每个下标 完全二叉树,所以显然使用数组进行存储。 访问指定下标的路径,且从底到上的方法: 绝对的核心算法,这里有以下几个点需要注意的: 都说到小顶堆的建立了,怎么能不加上推排序呢。 排序顺带输出了 堆中的路径(小顶堆的建立以及堆排序) 标签:存储 heap 路径 show temp 最小 code 建堆 说明 原文地址:https://www.cnblogs.com/Za-Ya-Hoo/p/12731423.html前言
题目
H[i]
。随后对任意给定的下标i
,打印从H[i]
到根结点的路径。输入格式
输出格式
i
,在一行中输出从H[i]
到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。样例
输入样例
5 3
46 23 26 24 10
5 4 3
输出样例
24 23 10
46 23 10
26 10
思路
前言也提到了,就算是相同的数组序列,不同的插入顺序,最终出来的堆都可能不一样。所以不能直接对完整序列进行处理,需要一个个插入操作。
小顶堆的插入是这样的:
因为使用数组存储,所以很方便的就可以找到某个结点的孩子结点,或者,某个结点的父结点。对于某个下标为i的结点来说,i/2向下取整就是该结点的父结点的位置。
注意,用数组存储二叉树时最好从下标1开始存储,因为可以方便的里面上述性质。实现
完整代码
#include
调整单个非叶结点函数
void myAdjust(int a[], int low, int high) { //调整单个非叶结点
int i = low;
int j = 2 * i; //从左子结点开始
while (j a[j + 1]) //双结点,先找出子结点里面最小的;单结点,就不变。不论单双结点,j最终指向子结点中的最小值。
j++;
if (a[i] > a[j]) { //将父结点与值最小的子结点判断是否要进行更换
int temp = a[i];
a[i] = a[j];
a[j] = temp;
i = j;
j = 2 * i;
}
else
break; //如果这轮不发生更换的话,那说明整棵树已经调整好了,因为从下往上调整的,所以底下的肯定也是调整好的
}
}
题目以外
小顶堆的性质是根结点的数必定是整个树中最小的。
推排序就是每次将根结点的数与末尾的数提取出来,并将最后一个叶结点的数填充到根结点的位置再对根结点进行调整使其再次称为小顶堆,直至最后将所有元素按照顺序提取出来,就是一个有序序列了。
所以在建好堆之后加一个提取过程就行了函数代码
void myHeapSort(int a[], int n) {
for (int i = 1; i
文章标题:堆中的路径(小顶堆的建立以及堆排序)
文章链接:http://soscw.com/index.php/essay/54364.html