堆排序的topk问题+归并排序+六大排序总结

回忆一下堆排序:

 

思路:

sift函数:调整,将父亲和孩子(左孩子和右孩子中最大的那个数) 然后和父亲比较,如果孩子大就将孩子的位子变为下一个父亲,往下拉 并且将孩子的值赋给他的父亲;j<=high 条件认可:

防止父亲在最后一层,魔法般的对应父亲大于孩子的情况,如果父亲大于孩子就将父亲的值写到父亲的位置上去,这和父亲落到最后位置的情况处理方式一样,十分巧妙。

建堆:农村包围城市,从最后一个堆开始调整 直到整个堆,调整为一个大根堆或是一个小根堆。

挨个出数:从最后一个数开始,循环处理,与第一个数(堆顶这个数是最大或者最小的数)交换,再次调成大根堆或者小根堆,注意第一次调整是high的值应该指向n-2的位置。利用循环,每次出来交换数,调整,直到将列表有序化。

言归正传:
堆排序应用之Topk问题:
现在有n个无序的数,设计算法得到前k个大的数(k<n)

例如:微博热门评论排行,网站排名......

解决思路: # k为常数

  • 排序后切片 O(nlogk)
  • 排序lowbi三人组(冒泡,选择,插入) O(kn)
  • 堆排序思路 O(nlogk)

所以我们在这里需要使用堆排序的降序调整:
如何修改升序?就改两个地方,如图:

Topk函数实现:

总结:


切片前k个数;

 

遍历k个数后面的数,选出大于堆顶的数据+每次都调整让对应堆顶始终是最小的数。

挨个出这k个数,与堆排序一样 注意:这里处理的列表是包含这k个数的并不是原列表!

 

 有想法的小伙伴可以在留言区下,说说你的思路,包括上面提及到的lowbi三人组,切片排序/..

归并排序

设计到递归,与快数排序一样,不是很好理解,但是好写一点。

原理:
n个数先拆到最后每个数都是单个数,递归到最大限度(low<high) 开始使用归并merge()

一层一层排序,直到最后一层排序就结束, 如图:

 

 核心merge函数实现:

 

 

 真正的归并排序实现:

 

 

 空间复杂度:
空间复杂度是:O(n)因为开辟了一个new_list列表来存储数据,所以就这样了。。

时间复杂度:
按照层数对应 每次归并排序(一次归并排序的时间复杂度是O(n))

所以,归并排序整体的时间复杂度是O(nlogn)

排序总结:

 快速归并堆排序的执行时间比较:

 

什么叫稳定性:
简单而言,就是说排序时,数是一个一个比较的,而不是一片一片扫描。

可以看出:冒泡、插入、归并排序稳定! 

显然,快速排序最快,但是也有最坏的情况,我们可以生成随机下标与第一个数进行交换,降低这种最坏的风险,降低这种概率。

综上所述,这就是本篇文章的所有内容,谢谢大家的观看,感谢!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值