「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」
堆排序
升序
一种非常正常的想法 空间复杂度O(N)
把数组中的元素全都push到小堆中,然后再取堆顶元素重新给数组,就可以达到升序的效果了
堆升序函数HeapSort
image-20211109215923477  
1  | c复制代码//升序  | 
堆排序测试函数
image-20211109220129388  
1  | c复制代码void testHeapSort()  | 
建堆(向上向下为建堆)
向上调整(建大堆)
上面做法一点毛病都没有,但是有要求了,空间复杂度为O(1) 也就是我们不可以在用Heap了
(这里的插入不是真正的插入,因为这些数据原本就在里面,我们就是在调堆,类似插入)
image-20211110004419158  
image-20211110004843299  
看到上面打印的结果我们看到建的是小堆,但是不好的是最小的在下标为0的位置,再次找次小的,从下标为一的位置再构建,这是不行的,因为会破坏结构,所以我们要重头建大堆,然后收尾交换
image-20211112004113756  
1  | c复制代码//真正玩法  | 
交换排序&&再向上调整
image-20211112011348827  
堆排序代码
1  | c复制代码//真正玩法  | 
堆排序测试
1  | c复制代码void testHeapSort()  | 
向下调整
排升序 构建小堆
image-20211110204752959  
排升序 构建大堆
有种就是这样玩的
image-20211110234106150  
堆排序
1  | c复制代码//真正玩法  | 
测试堆排序
1  | c复制代码void testHeapSort()  | 
降序
向上调整 (建小堆)
image-20211112012044528  
向下调整(建小堆)
image-20211112012356035  
建堆的时间复杂度
3.2.3 建堆时间复杂度因为堆是完全二叉树,而满二叉树也是完全二叉树,此处为了简化使用满二叉树来证明(时间复杂度本来看的就是近似值,多几个节点不影响最终结果):
image-20211111230047286  
image-20211111230800529  
所以时间复杂度是O(n)
本文转载自: 掘金