首先明确堆的性质: 堆是具有下列性质的完全二叉树,每个节点的值都大于或等于其左右孩子节点的值,称为大顶堆;或者每个节点的值都小于或等于其左右孩子节点的值,称为小顶堆。
基本思想:以大顶堆为例,将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根节点。将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就能得到n个元素中的次大值。如此反复执行,便能得到一个有序序列了。
主要是解决两个问题: (1)如何由一个无序序列构建成一个堆? (2)如果在输出堆顶元素后,调整剩余元素成为一个新的堆?
运行结果如下:
[13, 78, 65, 49, 76, 64, 27, 49, 38, 34, 12, 97][12, 76, 65, 49, 34, 64, 27, 49, 38, 13, 78, 97][13, 49, 65, 49, 34, 64, 27, 12, 38, 76, 78, 97][38, 49, 64, 49, 34, 13, 27, 12, 65, 76, 78, 97][12, 49, 38, 49, 34, 13, 27, 64, 65, 76, 78, 97][27, 49, 38, 12, 34, 13, 49, 64, 65, 76, 78, 97][13, 34, 38, 12, 27, 49, 49, 64, 65, 76, 78, 97][27, 34, 13, 12, 38, 49, 49, 64, 65, 76, 78, 97][12, 27, 13, 34, 38, 49, 49, 64, 65, 76, 78, 97][13, 12, 27, 34, 38, 49, 49, 64, 65, 76, 78, 97][12, 13, 27, 34, 38, 49, 49, 64, 65, 76, 78, 97]堆排序的运行时间主要是消耗在初始构建和在重建堆时的反复筛选上。 堆排序的时间复杂度为O(nlogn),由于堆排序堆原始记录的排序状态并不敏感,因此它无论是最好、最坏和平均时间复杂度均为O(nlogn),这在性能上显然优于之前所介绍的排序算法。由于记录的比较与交换是跳跃式进行,因此堆排序也是一种不稳定的排序算法。 同时,由于初始构建堆所需的比较次数较多,因此,它并不适合排序序列个数较少的情况。
文章只是作为自己的学习笔记,借鉴了网上的许多案例,如果觉得阔以的话,希望多交流,在此谢过…
新闻热点
疑难解答