现有n 个乱序数,都大于 1000 ,让取排行榜前十,时间复杂度为o(n), top10, 或者 topK,应用场景榜单Top:10,堆实现Top k

一、topK python实现
 
def topk(k, lst):
    top = [0 for i in range(k)] #生成一个长度为K 的有序列表
    for item in lst: #循环将要取 排行榜的列表
        for i in range(k-1,-1, -1):
            if item > top[i]: #在top 表中找到他的位置并插入
                top.insert(i+1,item)
                top.pop(0)  #删除值最小 索引为0的元素
                break  #找到了就打断

    print(top)
    return top

import random
lst = [i for i in range(100)]
random.shuffle(lst) #打乱列表
print(lst)

topk(10,lst)

# 运行结果:
[73, 63, 1, ......, 57, 9, 16, 85...... 40, 20, 97,... 84, 76, 87, 22, ......, 65, 93]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]

 

二、小根堆实现Topk 排行榜
  ###堆排序原理点击这儿查看本文

从一大堆数据里面输出前十,或者前 k 排行榜

- 实现思路:
取列表前十(k)构造一个小根堆 新列表, 然后从列表的第 10+1 (k+1)个位置往后循环,将每一个元素都同小根堆,根节点最小值做比较,如果比他大,说明该值应该在排行榜中,
将原根节点去掉换成换成该值,然后调整一次堆,直到拿来排行的列表循环结束,里面存储了Top 10 (k)然后将存了top值的小根堆排序,返回就好了

  • 下面程序,堆实现Top4, 你传入什么就实现什么
def heapsort(data, parent , high):

    new_par_node = parent
    j = 2*parent +1

    while j <= high:

        if j< high and data[j+1] < data[j]: #建立小根堆
            j += 1
        if data[j] < data[new_par_node]:  #建立小根堆
            data[j], data[new_par_node] = data[new_par_node], data[j]
            new_par_node = j
            j = 2*j +1
        else:
            break


def topk(k, lst):
    data = lst[:k]
    last_par_node = k//2 -1
    for node in range(last_par_node,-1, -1):
        heapsort(data, node, k-1)   

    for item in lst[k:]: #每一次从排行列表中选择一个元素出来
        if item > data[0]:  #如果他比 根节点大,说明他在排行榜中,把小顶(根节点最小值)去掉
            data[0] = item
            heapsort(data, 0, k-1)  #再 重调整 小根堆

    index = len(data) -1
    while  index >= 0:
        # 将小根堆降序 排序, 交换 根节点和最后的索引值
        data[0], data[index] = data[index], data[0]
        heapsort(data, 0, index-1)  #重调整 小根堆
        index = index -1  #无序区减一, 有序区多了一个

    return data

top4 = topk(4,  [2, 4, 1, 10, 23, 3, 4, 43,17])
print(top4)

# Top 4 排行榜前四为
[43, 23, 17, 10]
posted @ 2018-09-24 19:05  G1733  阅读(404)  评论(0编辑  收藏  举报