问题:找出列表中前K大的数(python实现)

本文介绍了如何使用Python实现快速找出列表中前k个最大值的方法,通过小根堆(defsift)和堆排序(heap_sort)算法,结合deftopk函数,详细展示了从创建堆到调整堆的过程。适合理解堆数据结构及其在排序中的应用。
摘要由CSDN通过智能技术生成
#问题:取出列表中前k大的数
def sift(li, low, high):    #小根堆
    # li指的是列表
    # low指的是堆的根节点位置
    # high指的是堆的最后一个元素的位置(作用值在于判断是否越界)
    i = low     #i最开始指向根节点
    j = 2*i + 1 #j开始是左孩子节点
    tmp = li[low]   #把堆存起来
    while j <= high :   #只要j位置有数
        if j+1 <= high and li[j+1] < li[j] :    #如果存在右孩子节点且右孩子节点更大
            j += 1  #j指向右孩子节点
        if li[j] < tmp:
            li[i] = li[j]
            i = j   #往下看一层
            j = 2*i + 1
        else:   #tmp更大,把tmp放到i的位置上
            li[i] = tmp     #把tmp放到某一级领导的位置上
            break
    else:
        li[i] = tmp     #把tmp放到叶子节点上


def topk(li, k):
    heap = li[0:k]
    for i in range((k-2)//2, -1, -1):
        sift(heap, i, k-1)
    #1.建堆
    for i in range(k, len(li)-1):
        if li[i] > heap[0]:
            heap[0] = li[i]
            sift(heap, 0, k-1)
    #2.遍历
    for i in range(k-1, -1, -1):
        heap[0], heap[i] = heap[i], heap[0]
        sift(heap, 0, i-1)
    #3.出数
    return heap


def heap_sort(li):
    #时间复杂度为O(n*logn)
    n = len(li)
    for i in range((n-2)//2, -1, -1):
        #i表示建堆的时候调整的部分的根的下标
        sift(li, i, n-1)
        #建堆完成了
    for i in range(n-1, -1,-1):
        #指向当前堆的最后一个元素
        li[0] , li[i] = li[i] , li[0]
        sift(li, 0, i-1)    #i-1是新的high



li = [i for i in range(100)]
import random
random.shuffle(li)

print(topk(li, 10))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值