回忆一下堆排序:
思路:
sift函数:调整,将父亲和孩子(左孩子和右孩子中最大的那个数) 然后和父亲比较,如果孩子大就将孩子的位子变为下一个父亲,往下拉 并且将孩子的值赋给他的父亲;j<=high 条件认可:
防止父亲在最后一层,魔法般的对应父亲大于孩子的情况,如果父亲大于孩子就将父亲的值写到父亲的位置上去,这和父亲落到最后位置的情况处理方式一样,十分巧妙。
建堆:农村包围城市,从最后一个堆开始调整 直到整个堆,调整为一个大根堆或是一个小根堆。
挨个出数:从最后一个数开始,循环处理,与第一个数(堆顶这个数是最大或者最小的数)交换,再次调成大根堆或者小根堆,注意第一次调整是high的值应该指向n-2的位置。利用循环,每次出来交换数,调整,直到将列表有序化。
言归正传: 例如:微博热门评论排行,网站排名...... 解决思路: # k为常数 排序后切片 O(nlogk)排序lowbi三人组(冒泡,选择,插入) O(kn)堆排序思路 O(nlogk)
所以我们在这里需要使用堆排序的降序调整: Topk函数实现: 总结: 遍历k个数后面的数,选出大于堆顶的数据+每次都调整让对应堆顶始终是最小的数。 挨个出这k个数,与堆排序一样 注意:这里处理的列表是包含这k个数的并不是原列表! 有想法的小伙伴可以在留言区下,说说你的思路,包括上面提及到的lowbi三人组,切片排序/.. 归并排序 设计到递归,与快数排序一样,不是很好理解,但是好写一点。 原理: 一层一层排序,直到最后一层排序就结束, 如图: 核心merge函数实现: 真正的归并排序实现: 空间复杂度: 时间复杂度: 所以,归并排序整体的时间复杂度是O(nlogn) 排序总结: 快速归并堆排序的执行时间比较: 什么叫稳定性: 可以看出:冒泡、插入、归并排序稳定! 显然,快速排序最快,但是也有最坏的情况,我们可以生成随机下标与第一个数进行交换,降低这种最坏的风险,降低这种概率。 综上所述,这就是本篇文章的所有内容,谢谢大家的观看,感谢!!!
堆排序应用之Topk问题:
现在有n个无序的数,设计算法得到前k个大的数(k
如何修改升序?就改两个地方,如图:
切片前k个数;
n个数先拆到最后每个数都是单个数,递归到最大限度(low
空间复杂度是:O(n)因为开辟了一个new_list列表来存储数据,所以就这样了。。
按照层数对应 每次归并排序(一次归并排序的时间复杂度是O(n))
简单而言,就是说排序时,数是一个一个比较的,而不是一片一片扫描。



