代码之家  ›  专栏  ›  技术社区  ›  Karthik

限制Go堆接口实现的优先级队列的大小

  •  5
  • Karthik  · 技术社区  · 7 年前

    在Java中,有一个具有size属性的PriorityQueue。我在这里也希望如此(如果我没有错的话)。

    用例:逐个读取数百万数据并将其发送到优先级队列。我只需要前5个计算元素,所以我只需要大小为5的堆/优先级队列。

    我正在尝试使用堆接口来实现这一点。至于我所看到的golang,动态数组会增加,但在我的情况下,这是不可行的。

    我指的是 https://play.golang.org/p/wE413xwmxE

    我怎样才能做到这一点?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Grzegorz Å»ur    7 年前

    如果您只需要N个元素中的前M个最小元素,那么请使用将为您提供最大元素的堆,并在其大小超过值M时修剪堆。然后按相反顺序从堆中获取元素。

    package main
    
    import (
        "container/heap"
        "fmt"
        "math/rand"
    )
    
    type IntHeap []int
    
    func (h IntHeap) Len() int           { return len(h) }
    func (h IntHeap) Less(i, j int) bool { return h[i] > h[j] }
    func (h IntHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
    
    func (h *IntHeap) Push(x interface{}) {
        *h = append(*h, x.(int))
    }
    
    func (h *IntHeap) Pop() interface{} {
        old := *h
        n := len(old)
        x := old[n-1]
        *h = old[0 : n-1]
        return x
    }
    
    const (
        n = 1000000
        m = 5
    )
    
    func main() {
        h := &IntHeap{}
        heap.Init(h)
    
        for i := 0; i < n; i++ {
            x := rand.Intn(n)
            heap.Push(h,x)
            if h.Len() > m {
                heap.Pop(h)
            }
        }
    
        r := make([]int, h.Len())
        for i := len(r) - 1; i >= 0; i-- {
            r[i] = heap.Pop(h).(int)
        }
        fmt.Printf("%v\n", r)
    }
    

    该算法的内存复杂度为M,时间复杂度为N+N*logm+M*logm。