基于python解决topk问题

现在有n个数,设计算法得到前k大的数 k<n

        1.解决思路:

                1.排序后切片 O(nlogn)

                2.lowB三人组排序 O(mn)

                3.堆排序 O(mlogn)

        2.堆排序解决topK问题

                1.取列表前K个元素建立一个小根堆,堆顶就是目前就是第K大的数

                2.依次向后遍历原列表,对于列表中的元素,如果小于堆顶则忽略该元素,如果大于堆顶则将该元素与堆顶元素交换位置,并且对堆进行一次调整

                3.遍历列表所有元素后倒序弹出堆顶

def sift_small(li, low, high):  # 小根堆
    """
    :param li: 所要排序的列表
    :param low: 树的根节点
    :param high: 树的深度
    :return:
    """

    i = low
    j = 2 * i + 1
    tmp = li[low]
    while j <= high:
        if j + 1 <= high and li[j + 1] < li[j]:
            j = j + 1
        if li[j] < tmp:
            li[i] = li[j]
            i = j
            j = 2 * i + 1
        else:
            break
    else:
        li[i] = tmp


def top_k(li, k):
    heap = li[0:k]
    #  1.创建堆
    for i in range((k - 2) // 2, -1, -1):  # 获取heap列表叶子节点的父节点
        sift_small(heap, i, k-1)  # 构建小根堆
    #  2.遍历堆
    for i in range(k, len(li)-1):  # 获取li列表从k之后的所有值
        if li[i] > heap[0]:  # 如果heap根节点小于列表中下标i的值
            heap[0] = li[i]  # 将根节点与列表中下标i的值位置替换
            sift_small(heap, 0, k-1)  # 取列表中元素前n大的数开始构建小根堆
    for i in range(k-1, -1, -1):  # 遍历小根堆使其按照从大到小排序
        heap[0], heap[i] = heap[i], heap[0]  # 置换根节点与叶子节点
        sift_small(heap, 0, i - 1)  # 每次将树更新一遍并且叶子节点减少一个
    return heap


List = [i for i in range(100)]
random.shuffle(List)
print(List)
print(top_k(List, 5))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值