堆排序(topk 问题)(NB)

发布时间 2023-08-12 22:53:30作者: zylyehuo

博客地址:https://www.cnblogs.com/zylyehuo/

# _*_coding:utf-8_*_
# 比较排序

import random


def sift(li, low, high):  # 堆的向下调整(小根堆)
    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
        li[i] = 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


ls = list(range(1000))
random.shuffle(ls)

print(topk(ls, 10))