学习堆排序前需要了解完全二叉树、大顶堆、小顶堆。
完全二叉树
完全二叉树是一种特殊的二叉树。除最后一层子节点可以不满且靠左,其他层都是满的(为什么要靠左,因为完全树可以转化成数组)
大顶堆
大顶堆:在完全二叉树的基础上,每个结点的值都大于或等于其左右孩子结点的值
小顶堆
小顶堆:在完全二叉树的基础上,每个结点的值都小于或等于其左右孩子结点的值
数组转化成堆
我们发现堆得特点
N[i]左子树:N[2i+1]
N[i]右子树:N[2i+2]
N[i]父节点:N[(i-1)/2]
堆排序基本思想
第一步:构建大顶堆
定义p指针指向父节点,定义c指针指向孩子节点。
1.找到兄弟节点当中的最大值
2.让子节点当中的最大值和父节点比较,如果子节点值大,则和父节点交换
3.调换完成之后我们需要将p指针指向c指向原来子节点当中的最大值,然后重复2、3直到c指 向null
第二步:堆顶元素和堆底元素进行互换,堆底元素不再参与排序
第三步:重新维护大顶堆
图示讲解:
第一步:构建大顶堆
指针p从尾到头遍历数组,当c指针小于数组长度时,父节点有左右孩子。找到兄弟节点最大值与父节点进行比较
我们最好定义一个临时空间存p指针的值,我们每次比较都和这个临时空间的值比较就可以。如果比较的c指针值比临时空间的值大就把值c指针的值赋给p指针(记得换完p指针指向c指向原来子节点当中的最大值),否则把临时空间的值赋给p指针。
上图可看出需要将2和9调换位置,并将p指针指向目前9的位置。结果如下。
后续构建大顶堆操作和上图一样