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

    1 python默认是小顶堆,想要实现大顶堆入堆的时候要添加负号,出堆的时候也添加负号,求前 k 大,用小根堆,求前 k 小,用大根堆,

    python用heapq模块来实现小顶堆,它有六个函数,其中四个函数用的最多,一个是heapify()直接对数组进行堆化,两个是heappush() heappop()分别是对已经堆化的插入元素和删除元素,一个是heapqreaplce()删除堆顶元素再插入元素进行堆化,由heappush() heappop()也可以完成,

    import heapq
    # 注意利用heappush的时候,它默认L是已经堆化的数组,所以必须从空数组开始插入,
    # 不堆化直接插入元素是错误的
    L = [444,6,5,8,2]
    heapq.heappush(L, 1)
    print(L)
    # [1, 6, 444, 8, 2, 5]
    
    L = []
    for i in [6,5,4,3,2]:
        # 这实际上是插入元素堆排序的方法,
        heapq.heappush(L, i)
    print(L)
    # [2, 3, 5, 6, 4]
    # heappop()弹出堆顶的元素
    m = heapq.heappop(L)
    print(m, L)
    
    # heapify()直接对数组进行堆化,
    # 如果堆并不是使用heappush创建的,应在使用heappush和heappop之前使用这个函数进行堆化
    L = [6,5,4,3,2]
    heapq.heapify(L)
    print(L)
    # [2, 3, 4, 6, 5]
    
    # 函数heapreplace用得没有其他函数那么多。它从堆中弹出最小的元素,再压入一个新元素。
    # 相比于依次执行函数heappop和heappush,这个函数的效率更高。
    heapq.heapreplace(L, 1)
    # 弹出堆顶的2,压入1,再堆化,
    print(L)
    
    # nlargest(n, iter)和nsmallest(n, iter),:分别用于找出可迭代对象iter中最大和最小的n个元素
    # 直接输出最小的n个数或最大的n个数,
    print(heapq.nsmallest(3, L))
    print(heapq.nlargest(3, L))
    # [1, 3, 4]
    # [6, 5, 4]
    View Code

    参考:https://blog.csdn.net/jamfiy/article/details/88185512

    https://www.cnblogs.com/cooffeeli/p/heapSort.html

    https://blog.csdn.net/loveliuzz/article/details/77618530

     2 堆排序代码

    def heap_sort(list):
        # 创建最大堆,
        for start in range((len(list) - 2) // 2, -1, -1):
            sift_down(list, start, len(list) - 1)
        # 堆排序
        for end in range(len(list) - 1, 0, -1):
            # 先把最大值放到数组的最后,再把第二大的数放到拿出来放到倒数第二个,再把第三大的数拿出来放到
            # 倒数第三个,依次类推
            list[0], list[end] = list[end], list[0]
            sift_down(list, 0, end - 1)
        return list
    # 最大堆调整
    # 这个函数的作用是,每次把start索引的节点放到它该放的位置,如果它已经大于左右节点了,结束,
    # 否则不断下沉,注意这里的下沉范围是从start节点到end节点,
    def sift_down(lst, start, end):
        root = start
        while True:
            # 由根节点索引计算出左节点的索引
            child = 2 * root + 1
            # 如果左节点索引越界,结束
            if child > end:
                break
            # 右节点索引未出界,且左节点的值小于右节点的值,
            # 这一步的目的是在左右节点中选出一个大的来,与根节点比较
            if child + 1 <= end and lst[child] < lst[child + 1]:
                # 更新child为右节点
                child += 1
            # 如果大的子节点大于根节点时,则交换二者的值,
            # 并把根节点更新为子节点,继续最大堆
            if lst[root] < lst[child]:
                lst[root], lst[child] = lst[child], lst[root]
                root = child
            else:
                break
    l = [8,12,9,30,1,3,4,5,23,6,7]
    print(heap_sort(l))
    View Code

    ttt

  • 相关阅读:
    Spring 拦截器postHandle无法修改Response的原因
    使用AShot进行网页全页截图
    60句简短的话 句句在理
    天使
    路过青春的合欢树
    Velocity日期格式化
    高斯模糊的Java实现
    MyBatis架构与源码分析<资料收集>
    柳青(Jean)英文演讲集合
    hive sql 常见异常
  • 原文地址:https://www.cnblogs.com/xxswkl/p/12705673.html
Copyright © 2011-2022 走看看