持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情
堆排序
基本思路
(1)大/小顶堆:每一个结点值都大于(小于)或等于孩子结点(实际上堆可以看成一颗完全二叉树)
(2)堆排序:利用这种堆的结构进行排序。如:对一个待排序列进行堆排序,需要先建堆(大顶堆),这时我们可以结合大顶堆的性质,取堆顶元素,取完堆顶元素后我们要重新调整大顶堆,再取堆顶数据再调整。在这个过程会涉及建堆,调整堆。所以要清楚这个堆有什么特点。
(3)堆:堆通常是一个可以被看做一棵完全二叉树的数组对象,因为堆可以看做是完全二叉树。则完全二叉树的特点:
a. 假设完全二叉树总节点数为n,则会有n/2个父节点
b. 对一棵有n个结点的完全二叉树的结点按层序编号, 则对任一结点i (1≤i≤n) ,若2i>n,则结点i无左孩子,否则左孩子的结点为2i;如果2i+1>n,则结点i无右孩子,否则右孩子结点为2i+1
c. 完全二叉树的叶子结点也只能出现最后两层上
对于上面完全二叉树中(1)(2)中这个关系对我们进行堆排序进行构建堆,调整堆很关键。
(4)手动模拟构造堆:(这里i从1开始)
step1:对待排序数组按完全二叉树方式排列出来,自下往上逐步调整。先找到最后一个父节点n/2=4,判断i=4结点的孩子结点较大是否大于父节点,若大于则交换数据
step2-5:继续向上调整,但是在调整的过程中,可能回破坏下一级的大顶堆结构,所以还需要向下检查,如图中step4中i=1中53和87交换后,破坏了i=3处大顶堆的结构,则需要调整。
总结:
今天先梳理堆排序的一个整体思路,明天蒋继续分享代码的实现