堆以及堆排序实现

来源:互联网 发布:新域名 访问升级 编辑:程序博客网 时间:2024/05/07 05:30

1.今天实现了一下堆排序,这里的堆是指二叉堆,至于二项堆和斐波那契堆以后再说。

先看二叉堆的定义:

二叉堆是完全二叉树或近似完全二叉树。

满足特性是:父亲节点的值大于等于(小于等于)左右孩子的值,并且左右子树也是二叉堆。对应的二叉堆是大顶堆(小顶堆)。

二叉堆是完全二叉树,可以用线性表来存储。

2.实现堆排序时的想法:

(1)一个关键点是堆的调整,调整的时候一定要注意先找到左右孩子中较大(小)的数的位置,这是可能被置换的位置,因为置换后,这个被置换的位置就变成了新的要调整的位置了,我们需要从它开始往下继续调整(因为置换后,有可能破坏了下边的堆结构)。

(2)步骤:先把数组调整成大(小)顶堆。开始调整的位置为length/2向下取整,从这开始,一直调整到根节点,即数组下标为1的值。

                      然后把堆顶元素和最后一个元素置换,继续调整剩下的length-1 个数了,因为这里共n-1次调整,每次开始调整位置都是从根节点开始调整,只是变了长度,所以这里可以循环调用调整函数n-1次。

3.下边是具体代码

4.复杂度分析

时间消耗主要是:(1)先把数组调整成堆,即建堆的过程。消耗时间为:1+2+...+log2n ,其中数值代表的是调整位置最多置换的次数(个人理解),它是线性的,为O(n).

                          (2)调整堆的过程,这在建堆和排序时都会被用到,因为在后边的n-1次调整中,开始位置都是从根节点开始,即最多有log2n次置换

                          (3)所以排序时为O(nlogn)

空间复杂度为O(1);

5.特点

堆排序和直接选择排序相反:在任何时刻堆排序中无序区总是在有序区之前,且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止。

其他性能:由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。

堆排序是不稳定的排序。

1 0