zoukankan      html  css  js  c++  java
  • python堆排序heapq

    python堆排序heapq

    Python堆排序heapq模块实现了一个适用于Python列表的最小堆排序算法。

    堆是一种树形数据结构,其中子节点与父节点之间是一种有序关系。最大堆(大顶堆)中父节点大于或等于两个子节点,最小堆(小顶堆)父节点小于或等于两个子节点。Python的heapq模块实现了一个最小堆。

    堆排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。

      堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:

    同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子

    该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是:

    大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]  

    小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]  

    ok,了解了这些定义。接下来,我们来看看python中堆排序的基本思想及基本操作:

    创建堆

    创建堆有两种方式,heappush()和heapify()。

    import heapq
    data = [1,5,3,2,8,5]
    heap = []
    
    for n in data:
        heapq.heappush(heap, n)
    

    如果数据已经存在于内存中,使用heapify()原地重新组织列表中的元素会更加高效。

    import heapq
    data = [1,5,3,2,8,5] 
    heapq.heapify(data)

    上述两种方法得到的堆是一样的。

    还有一种merge()方法,可以从多个可迭代对象中创建一个堆,相当于heapq.heapify(itertools.chain(*iterables))

    访问堆内容

    堆创建好之后,可以使用heappop()删除有最小值的元素。

    import heapq
    data = [1,5,3,2,8,5]
    heapq.heapify(data)

    print(heapq.heappop(data)) # print 1

    如果希望在一个操作中删除现有最小元素并替换成新值,可以使用heapreplace()。

    import heapq
    data = [1,5,3,2,8,5] 
    heapq.heapify(data)
    heapq.heapreplace(data,10)

    堆的数据极值

    heapq还包括两个检查可迭代对象的函数,查找其中包含的最大值与最小值的范围。

    import heapq
    data = [1,5,3,2,8,5] print (heapq.nlargest(3, data)) print (heapq.nsmallest(3, data))

    输出结果如下:

    [8, 5, 5]

    [1, 2, 3]

    只有在n值比较小的情况下nlargest()和nsmallest()才比较高效。

    这个两个函数还接受一个关键字参数key, 用于更加复杂的数据结构中。

    portfolio = [

        {'name': 'IBM', 'shares': 100, 'price': 91.1},
        {'name': 'AAPL', 'shares': 50, 'price': 543.22},
        {'name': 'FB', 'shares': 200, 'price': 21.09},
        {'name': 'HPQ', 'shares': 35, 'price': 31.75},
        {'name': 'YHOO', 'shares': 45, 'price': 16.35},
        {'name': 'ACME', 'shares': 75, 'price': 115.65}
    ]
    cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
    expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])

    上面代码对每个元素进行比较时, 会以price的值进行比较。

    实战

    实现堆排序

      >>> from heapq import *

    >>> def heapsort(iterable):
    ...     'Equivalent to sorted(iterable)'
    ...     h = []
    ...     for value in iterable:
    ...         heappush(h, value)
    ...     return [heappop(h) for i in range(len(h))]
    ...
    

    由于堆中的元素可以为元组,所以可以对带权值的元素进行排序。

      >>> from heapq import *

    >>> h = []
    >>> heappush(h, (5, 'write code'))
    >>> heappush(h, (7, 'release product'))
    >>> heappush(h, (1, 'write spec'))
    >>> heappush(h, (3, 'create tests'))
    >>> heappop(h)
    (1, 'write spec')
  • 相关阅读:
    poj2104 Kth-Number
    bzoj2120 数颜色
    hdu5145 NPY and girls
    bzoj2734 集合选数
    bzoj3732 NetWork
    bzoj2152 聪聪可可
    hdu2036(多边形面积)
    超大次幂思路
    hdu 2030 统计汉字个数
    Hibernate 配置文件与映射文件 总结
  • 原文地址:https://www.cnblogs.com/cjtds/p/12596870.html
Copyright © 2011-2022 走看看