内容介绍
堆排序简介
前面我们已经介绍了堆结构,也能够构造一个堆结构。如果对堆结构不了解的同学可以看一下之前的文章《动画学堆结构,一篇一看就懂的堆结构文章》。我们稍微回顾一下,根节点最大的堆叫做最大堆
或大根堆
,如下图:
获取最大堆的最大值,其实就是获取堆顶的元素。对于堆这种数据结构通常是将堆顶的元素和堆中最后一个元素换位置,最大值就到了最后一个位置,然后从堆中排除这个最大的元素,当最后一个元素交换到最前面时,此时就不满足堆的性质了,我们需要将最前面这个元素通过ShiftDown
(下沉)的手段让堆继续满足堆的规则。
堆获取最大值可以分成两个步骤:
- 将堆中最前面的最大值和最后一个元素交换位置。
- 使用
ShiftDown
让最前面的元素下沉到合适的位置,依然满足堆的性质。
动画演示效果如下:
堆排序的思想
我们知道堆顶的元素就是堆中的最大值,因此我们每次从堆中取出并移除最大值(其实是将堆顶的最大值移动到了堆的最后面),然后ShiftDown
使这个二叉树依然满足堆的规则,堆中第二大的数据就会到堆顶,再次取出堆顶的最大值,其实就是所有数据中的第二大值,依次类推,于是就完成了堆排序。
堆排序动画演示
一般没有特殊要求排序算法都是升序排序,小的在前,大的在后。数组由{5, 3, 1, 9, 7, 2, 8, 6} 这8个无序元素组成。
堆排序分析
如上图所示,当我们将堆顶的最大值9移除后,堆中的第二大值8就会到堆顶来。当我们再次将8移除后,堆中剩余元素的最大值会到堆顶来。
堆删除8后的效果:
堆删除7后的效果:
堆删除6后的效果:
堆删除5后的效果:
堆删除4后的效果:
堆删除3后的效果:
堆删除2后的效果:
堆删除1后的效果:
我们可以看到堆排序算法的步骤:
- 把无序二叉树构建成二叉堆。
- 循环删除堆顶元素,移到数组尾部,调整二叉堆,得到新堆中的最大值放到堆顶。
堆排序代码编写
public class HeapSort {
public static