• 关于topN问题的几种解决方案


    在系统中,我们经常会遇到这样的需求:将大量(比如几十万、甚至上百万)的对象进行排序,然后只需要取出最Top的前N名作为排行榜的数据,这即是一个TopN算法。常见的解决方案有三种:

    (1)直接使用List的Sort方法进行处理。

    (2)使用排序二叉树进行排序,然后取出前N名。

    (3)使用最大堆排序,然后取出前N名。

       第一种方案的性能是最差的,后两种方案性能会好一些,但是还是不能满足我们的需求。最主要的原因在于使用二叉树和最大堆排序时,都是对所有的对象进行排序,而不是将代价花费在我们需要的少数的TopN上。对于堆结构来说,并不需要你获取所有的数据,只需要对前N个数据进行处理。因此可以通过堆栈的进入排出,用小顶堆实现,调整最小堆的时间复杂度为lnN,总时间复杂度为nlnN

    myheap:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-


    # 最小堆化heap
    def siftdown(heap, start, end):
    while True:
    left_child = start * 2 + 1
    if left_child > end:
    break
    if left_child + 1 <= end:
    if heap[left_child] > heap[left_child+1]:
    left_child += 1

    if heap[left_child] < heap[start]:
    heap[left_child], heap[start] = heap[start], heap[left_child]
    start = left_child
    else:
    break


    def minheapstyle(heap):
    first = len(heap) // 2 - 1
    for x in xrange(first, -1, -1):
    siftdown(heap, x, len(heap)-1)


    def push(heap, item):
    heap.append(item)
    minheapstyle(heap)


    def pushpop(heap, item):
    if heap[0] < item:
    heap[0] = item
    minheapstyle(heap)


    if __name__ == '__main__':
    heap = [10,4,5,3,5,6,2]
    minheapstyle(heap)
    print heap
    TOPN:
    import myheap


    def findminn(list, n):
    heap = []
    for x in list:
    if len(heap) < n:
    myheap.push(heap, x)
    else :
    myheap.pushpop(heap, x)
    return heap


    if __name__ == '__main__':
    l = [5,6,7,8,9,10,5646]
    #n=5
    heap = findminn(l,5)
    print heap

    虽然python有类似的最小堆结构,但是当我们需要处理更复杂的问题时,可能依然需要自己定制。

  • 相关阅读:
    Anaconda下载及安装教程
    机器学习之一元线性回归模型
    PyCharm下载及安装教程
    Python基础之数据类型、变量、常量
    新旧代码的兼容(c和c++)
    埃拉托斯特尼--筛法 c++求质数,用bitset类型
    使用预处理器进行调试
    刷题-网易2018实习生招聘笔试题
    深度优先搜索-DFS遍历图-C++
    图--邻接矩阵c++
  • 原文地址:https://www.cnblogs.com/silencestorm/p/8512504.html
Copyright © 2020-2023  润新知