Python使用heapq实现小顶堆(TopK大)、大顶堆(BtmK小) | 四号程序员

Python使用heapq实现小顶堆(TopK大)、大顶堆(BtmK小)

需1求:给出N长的序列,求出TopK大的元素,使用小顶堆,heapq模块实现。

01 import heapq
02 import random
03  
04 class TopkHeap(object):
05     def __init__(self, k):
06         self.k = k
07         self.data = []
08  
09     def Push(self, elem):
10         if len(self.data) < self.k:
11             heapq.heappush(self.data, elem)
12         else:
13             topk_small = self.data[0]
14             if elem > topk_small:
15                 heapq.heapreplace(self.data, elem)
16  
17     def TopK(self):
18         return [x for x in reversed([heapq.heappop(self.data) for x in xrange(len(self.data))])]
19  
20 if __name__ == "__main__":
21     print "Hello"
22     list_rand = random.sample(xrange(1000000), 100)
23     th = TopkHeap(3)
24     for i in list_rand:
25         th.Push(i)
26     print th.TopK()
27     print sorted(list_rand, reverse=True)[0:3]

上面的用heapq就能轻松搞定。

变态的需求来了:给出N长的序列,求出BtmK小的元素,即使用大顶堆。

heapq在实现的时候,没有给出一个类似Java的Compartor函数接口或比较函数,开发者给出了原因见这里:http://code.activestate.com/lists/python-list/162387/

于是,人们想出了一些很NB的思路,见:http://stackoverflow.com/questions/14189540/python-topn-max-heap-use-heapq-or-self-implement

我来概括一种最简单的:

将push(e)改为push(-e)、pop(e)改为-pop(e)。

也就是说,在存入堆、从堆中取出的时候,都用相反数,而其他逻辑与TopK完全相同,看代码:

01 class BtmkHeap(object):
02     def __init__(self, k):
03         self.k = k
04         self.data = []
05  
06     def Push(self, elem):
07         # Reverse elem to convert to max-heap
08         elem = -elem
09         # Using heap algorighem
10         if len(self.data) < self.k:
11             heapq.heappush(self.data, elem)
12         else:
13             topk_small = self.data[0]
14             if elem > topk_small:
15                 heapq.heapreplace(self.data, elem)
16  
17     def BtmK(self):
18         return sorted([-x for x in self.data])

经过测试,是完全没有问题的,这思路太Trick了……

Python使用heapq实现小顶堆(TopK大)、大顶堆(BtmK小)的更多相关文章

  1. 数据结构:堆排序 (python版) 小顶堆实现从大到小排序 | 大顶堆实现从小到大排序

    #!/usr/bin/env python # -*- coding:utf-8 -*- ''' Author: Minion-Xu 小堆序实现从大到小排序,大堆序实现从小到大排序 重点的地方:小堆序 ...

  2. python中heapq堆的讲解

    堆的定义: 堆是一种特殊的数据结构,它的通常的表示是它的根结点的值最大或者是最小. python中heapq的使用 列出一些常见的用法: heap = []#建立一个常见的堆 heappush(hea ...

  3. Python中heapq与优先队列【详细】

    本文始发于个人公众号:TechFlow, 原创不易,求个关注 今天的文章来介绍Python当中一个蛮有用的库--heapq. heapq的全写是heap queue,是堆队列的意思.这里的堆和队列都是 ...

  4. python中heapq对dict进行排序

    问题: 想从以下形式的dict中取value最大的2个key-value的key dict_num_num = {0: 0.07374631268436578, 1: 0.16307692307692 ...

  5. PTA 最小堆插入元素和删除堆顶(无哨兵元素) (20分)

    PTA 最小堆插入元素和删除堆顶(无哨兵元素) (20分) 对于给定的最小堆(优先队列),分别实现插入元素和删除堆顶的函数. 函数接口定义: int insertIntoHeap(struct Hea ...

  6. python 关于heapq模块的随笔

    heapq模块提供了很多高级功能可以通过help(heapq)查看详细文档: 要点: 1优先级队列让我们可以按照重要程度来处理元素,而不是先进先出 2使用heapq可以应对长列表,因为heap不是复杂 ...

  7. Java堆外内存之三:堆外内存回收方法

    一.JVM内存的分配及垃圾回收 对于JVM的内存规则,应该是老生常谈的东西了,这里我就简单的说下: 新生代:一般来说新创建的对象都分配在这里. 年老代:经过几次垃圾回收,新生代的对象就会放在年老代里面 ...

  8. 【最短路Dijistra】【一般堆优化】【配对堆优化】

    突然觉得堆优化$O(log_n)$的复杂度很优啊,然而第n次忘记了$Dijistra$怎么写QAQ发现之前都是用的手写堆,这次用一下$stl$ #include<bits/stdc++.h> ...

  9. 二叉堆复习(包括d堆)

    要期中考了……我真的是什么也不会啊,书都没看过TAT. 好吧整理一下二叉堆,这里就以最大堆为例好了. 首先二叉堆其实是一棵CBT,满足父节点的键值大于左右子节点的键值(wikipedia把这个叫键值, ...

随机推荐

  1. H3C HCSE 官方培训胶片(中文) 下载

    H3C HCSE 官方培训胶片(中文) 点击文件名下载 HM-040 OSPF路由协议(V5.1).ppt HM-041 BGP协议原理及配置(V5.0).ppt HM-041 BGP协议原理及配置( ...

  2. Vistual Studio 2012更换皮肤

    早就装上VS2012了,可是除了在家里练习玩玩的时候使用外,在公司都还在用2010,也没好好研究过2012.这两天把公司的电脑换了系统,也就把vs换成了2012.可是看着不是白白的皮肤就是深色的皮肤, ...

  3. spring+mybatis利用interceptor(plugin)兑现数据库读写分离

    使用spring的动态路由实现数据库负载均衡 系统中存在的多台服务器是"地位相当"的,不过,同一时间他们都处于活动(Active)状态,处于负载均衡等因素考虑,数据访问请求需要在这 ...

  4. boost::property_tree读取解析ini文件--推荐

    boost::property_tree读取解析ini文件 #include "stdafx.h" #include <iostream> #include <b ...

  5. Javascript 生成指定范围数值随机数

    JavaScript对随机数的介绍比较少,所以今天分享一下有关随机数的一些事儿.希望能对大家有点小帮助. 主要的公式就是parseInt(Math.random()*(上限-下限+1)+下限); Ma ...

  6. js下firstElementChild firstChild 以及childNodes和children方法

    一. <div> <p>123</p> </div> 在上面这段代码中,如果使用以下js代码 var oDiv=document.getElementB ...

  7. 【AllJoyn专题】基于AllJoyn和Yeelink的传感器数据上传与指令下行的研究

    接触高通物联网框架AllJoyn不太久,但确是被深深地吸引了.在我看来,促进我深入学习的原因有三点:一.AllJoyn开源,对开源的软硬件总会有种莫名的喜爱,虽然或许不会都深入下去:二.顺应潮流,物联 ...

  8. Thinkphp入门 一 (45)

    原文:Thinkphp入门 一 (45) 什么是框架? 就是一堆代码的集合,这些代码可以有变量.常量.函数.类等等.这些代码彼此紧密联系,彼此有合作关系.里边还有设计模式:MVC.单例.工厂等等. 为 ...

  9. ResourceManager架构解析

    RM作为master管理着所有的集群资源,它会和NM和特定application的AM共同工作 1. NodeManagers NM从RM中获得指令,并管理着单节点上可用资源 2. Applicati ...

  10. ZOJ 3829 贪心 思维题

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3829 现场做这道题的时候,感觉是思维题.自己智商不够.不敢搞,想着队友智商 ...