堆排序(O(n*logn))及python中堆排序的内置函数

  • 堆排序过程:

     1.从下往上建堆,把每个小堆都向下调整为一个大根堆(sift),最后建立起一个完整的大根堆。

     2. 从栈顶开始,将栈顶元素与最末元素交换(使最大元素在列表最末),然后将1~(n-1)的元素再向下调整(sift);重复操作,得到一个升序的序列;

  • 堆排序代码:
# 堆的向下调整
def sift(alist,low,high):
    '''
    :param alist: 列表
    :param low:堆得根节点位置
    :param high:堆得最后一个元素位置
    :return:list
    '''
    i=low     #当前堆的根节点
    j=2*i+1   #i的左孩子
    tmp=alist[i]  # 取出对顶元素
    while j<=high:
        if j+1<=high and alist[j+1]>alist[j]:  # 若右孩子>左孩子,让j指向右孩子
            j=j+1
        if tmp<alist[j]:
            alist[i]=alist[j]
            i=j
            j=2*i+1
        else:   # 不用调整
            alist[i]=tmp
            break
    if j>high:
        alist[i]=tmp   # 将tmp放到叶子节点的位置

# 堆排序
def heap_sort(alist):
    # 建堆,从最小堆开始
    n=len(alist)-1
    for i in range((n-1)//2,-1,-1): # 从孩子找父亲 i=(j-1)//2, 从最后一个父亲节点开始对当前子树进行排序
        # i表示建立堆的时候调整部分子树的根节点
        sift(alist,i,n)
    # 挨个取堆顶元素
    for j in range(n,-1,-1):
        # j 一直指向堆的最后一个元素
        alist[0],alist[j]=alist[j],alist[0]
        sift(alist,0,j-1)
  • python内置函数实现堆排序 
# 内置函数实现堆排序
'''python内置模块:heapq
常用函数:
heapify(x)
heappush(heap,item)   加元素
heappop(heap)'''

import heapq
import random
alist=list(range(15))
random.shuffle(alist)
heapq.heapify(alist) # 建堆(小根堆)
new=[]
for i in range(15):
    new.append(heapq.heappop(alist)) # 取出堆顶元素
  • 堆排序适用场景:
    • topk问题:找出前k大/小的数。(找出列表前k个数建立一个小根堆,然后将列表中剩下的元素与堆顶元素相比较,并且进行调整)O(nlogk)
# 堆的向下调整
def sift(alist,low,high):
    '''
    :param alist: 列表
    :param low:堆得根节点位置
    :param high:堆得最后一个元素位置
    :return:list
    '''
    i=low     #当前堆的根节点
    j=2*i+1   #i的左孩子
    tmp=alist[i]  # 取出对顶元素
    while j<=high:
        if j+1<=high and alist[j+1]<alist[j]:
            j=j+1
        if tmp>alist[j]:
            alist[i]=alist[j]
            i=j
            j=2*i+1
        else:   # 不用调整
            alist[i]=tmp
            break
    if j>high:
        alist[i]=tmp   # 将tmp放到叶子节点的位置

# topk
def topk(alist,k):
    # 建堆
    heap=alist[:k]
    for i in range((k-2)//2,-1,-1):
        sift(heap,i,k-1)
        # 遍历
        for i in range(k,len(alist)-1):
            if alist[i]>heap[0]:
                heap[0]=alist[i]
                sift(heap,0,k-1)
        # 挨个取堆顶元素
        for j in range(k-1, -1, -1):
            heap[0], heap[j] = heap[j], heap[0]
            sift(heap, 0, j - 1)
        return heap

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值