堆排序

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

posted on 2020-04-15 15:32  吃我一枪  阅读(157)  评论(0编辑  收藏  举报

导航