前情了解:
要想了解堆排序的过程,首先得知道什么是堆?
要想了解什么是堆,首先得知道什么是二叉树?
而在堆排序中使用的完全二叉树只是二叉树的一种,所以先得了解什么是完全二叉树?
完全二叉树(百度百科):
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
简单来说,就是一棵从上往下,从左往右的必须依次布满
节点的树就是完全二叉树。
例如:
了解了完全二叉树之后,就可以来看一下什么是堆?
堆实际上就是一个完全二叉树,不同的地方在于:它是有规律的完全二叉树,也就是说堆一定是完全二叉树,但完全二叉树却不一定是堆。
对于一棵完全二叉树来说,如果它的任意一个父节点的值都大于或等于它的两个子节点,这样的堆叫做大根堆
,又称最大堆(大顶堆);
相反如果一棵完全二叉树,它的任意一个父节点的值都小于或等于它的两个子节点,这样的堆叫做小根堆
,又称最小堆(小顶堆)。
如下图示:
了解完以上概念之后,就可以正式进行堆排序了,拿到一组无序的数据后,先把这组数据整理成一个大根堆或小根堆,至于选择哪一个,取决于你的排序是升序还是降序,一般来说升序建大根堆,降序建小根堆
主题思路:
堆排序主要分为两步,以大根堆为例进行讲解:
- 将初始堆也就是一个完全二叉树构建成大根堆
- 将堆顶数据与末节点进行交换得到最大的数据
- 重复上述步骤
注:在整个排序过程中,堆必须始终保证是大根堆,为森么嘞?
只有堆始终是大根堆,才能保证每次拿到的数据是最大的,并且在调整的过程中,当前子树中的最大数据位于根节点,便于下一次拿到最大的数据
具体过程:
拿到一组数据{ 1,3,4,8,9,2 }之后:
Step1:将初始堆构建成大根堆
a.无序序列的结构如下:
b.大根堆调整的过程如下:
我们先从最后一个非叶子结点开始(叶结点自然不用调整,第一个非叶子结点size/2-1=2,也就是上图的4结点),从左至右,从下至上进行调整。
- 在以4节点为根节点的子树中,符合大根堆规律,不需要调整;
- 在以3节点为根节点的子树中,{3, 9, 8}三个节点中,节点9最大,此时交换节点3与节点9,如下图示: