zoukankan      html  css  js  c++  java
  • 关于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有类似的最小堆结构,但是当我们需要处理更复杂的问题时,可能依然需要自己定制。

  • 相关阅读:
    【转载】面对酱紫的情况,肿么办哇?
    webform 基础
    LINQ 语句实现分页
    LINQ to SQL 语句
    发送邮件&Timer
    treeview递归
    进程&线程
    登录框记住账号
    窗体-对话框,记事本
    日期与地区的三级联动
  • 原文地址:https://www.cnblogs.com/silencestorm/p/8512504.html
Copyright © 2011-2022 走看看