选择问题——选出第K个最大的元素

最近在读《数据结构与算法分析(C语言描述)》,在优先队列(堆)一节中,作者总结了关于“选择问题——求第k个最大的元素”的几种思路,在此简单总结一下:

第一种

将这 N 个数读进一个数组中,再通过某种简单的算法,比如冒泡排序、选择排序等,以递减顺序将数组进行排序,然后返回位置k上的元素。假设使用最简单的排序算法,则运行时间为 O(N2)

第二种

这是对第一种算法的简单优化。申请一个大小为 k 的数组,然后先把前k个元素读入数组并以递减顺序进行排序。接着,将剩下的元素再逐个读入。当新元素被读到时,如果它小于数组中的第 k 个元素则忽略,否则将其放到数组中正确的位置上(就是插入排序啊!),同时将数组中最后一个元素挤出数组。当算法终止时,位于第k个位置上的元素就是最终结果,即第 k 个最大的元素。
该算法的平均运行时间为O(Nk),但是最差时间为 O(N2)

第三种

简单来说:建最大堆!
N 个元素读入数组,然后对该数组执行BuildHeap算法(就是将这 N 个元素进行建堆,当然也可以边读数边建堆),最后,执行k DeleteMin 操作(就是删除根结点,也就是删除当前堆中最大的那个数)。从该堆中最后提取的那个元素就是我们的答案。

时间复杂度分析:

  • 如果使用 BuildHeap ,构造堆的最坏情形用时是 O(N) ,而每次 DeleteMin 用时 O(logN) (要随时调整堆),由于有 k DeleteMin,因此总运行时间为 O(N+klogN)
  • 如果 k=O(N/logN) ,那么运行时间取决于 BuildHeap 操作,即 O(N)
  • 对于大的 k 的值,运行时间为O(klongN)

第四种

算是第二种和第三种思路的结合。
也就是用堆来实现大小为 k 的数组S,前 k 个元素通过调用一次BuildHeap,以总时间 O(k) 被置入堆中,处理其余每个元素的时间为 O(1) (检测元素是否进入数组)再加上时间 O(longk) (在必要时删除根结点并插入新元素)。因此总的时间为 O(k+(Nk)longk)=O(Nlongk)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值