当前位置:  开发笔记 > 编程语言 > 正文

有队列实现吗?

如何解决《有队列实现吗?》经验,为你挑选了4个好方法。

任何人都可以提出转到容器,简单快速的FIF /队列,Go有3个不同的容器:heap,listvector.哪一个更适合实现队列?



1> Marwan Burel..:

事实上,如果你想要的是一个基本的,易于使用的fifo队列,slice提供了你所需要的一切.

queue := make([]int, 0)
// Push to the queue
queue = append(queue, 1)
// Top (just get next element, don't remove it)
x = queue[0]
// Discard top element
queue = queue[1:]
// Is empty ?
if len(queue) == 0 {
    fmt.Println("Queue is empty !")
}

当然,我们假设我们可以信任追加和切片的内部实现,以避免无用的调整大小和重新分配.对于基本用法,这是完全足够的.


此实现的问题在于其内存使用量与出队呼叫数量成正比.
这不是一个好方法,因为每次`queue [1:]`完成时,它会将切片的开始移动到指向下一个元素,但不释放出列元素使用的间隔.实际上,它在切片存储中具有无限的内存增长.此外,如果排队的元素是指针或包含指针的结构,则底层切片存储将保留内存到出队元素,从而导致进一步的内存泄漏.
[SliceTricks:如何使用切片进行矢量化处理](https://code.google.com/p/go-wiki/wiki/SliceTricks).
问题在于该元素会经常被复制.这根本不是问题(复制速度很快),但要记住这一点.
@Florian,此示例代码使用`[] int`进行复制。相反,如果它是`Foo struct {/ *很多字段* /}类型的,则通常使用[[] * Foo`并将队列作为指针,并且根本不会复制元素。(然后,您还想执行“ queue [0] = nil; queue = queue [1:]”以丢弃第一个元素,并从队列中删除对该元素的引用)。
我刚刚在Go 1.11.2中使用了指向结构的指针对其进行了测试。找不到内存泄漏。看起来是一种简单而好的方法。也不需要设置零。https://play.golang.org/p/QAujWCS20xc
@kostya和@tul的评论不正确。只要没有足够的容量容纳新元素,`append`就会创建一个新的后备数组。因此,只要扔掉旧的切片`queue = queue [1:]`,内存使用情况就不会无限。如果切片很大,则可能仍需要一段时间才能收回该内存。

2> saarrrr..:

令人惊讶的是,没有人建议缓冲通道,无论如何,对于大小限制的FIFO队列.

//Or however many you might need + buffer.
c := make(chan int, 300)

//Push
c <- value

//Pop
x <- c


对于不需要持久性的小队列,这应该是默认的事情.即使您正在写入磁盘上的无界队列,从通道写入和读取通常也是一种很好的方法.
是不是x = < - 阻塞呼叫?如果c为空,那么你的go路由可能会挂起,直到队列被补充为止.那不是你想要一个简单的队列数据结构的行为吗?
@ anaken78:select/default子句无法修复,对吧?https://gobyexample.com/non-blocking-channel-operations

3> Evan Shaw..:

矢量或列表应该可以工作,但矢量可能是要走的路.我这样说是因为vector可能比list更少分配和垃圾收集(在当前的Go实现中)相当昂贵.但是,在一个小程序中,它可能无关紧要.


注意:Go 1直接删除容器/矢量包.应更新使用容器/向量的代码以直接使用切片.[Go 1发行说明](http://golang.org/doc/go1):[已删除的软件包](http://golang.org/doc/go1#deleted).[SliceTricks如何使用切片进行矢量化处理](https://code.google.com/p/go-wiki/wiki/SliceTricks).
切片在删除元素时很烂。Slice不能替代可变向量。

4> VonC..:

为了扩展实现方面,Moraes在他的要点中提出了一些来自队列和堆栈的结构:

// Stack is a basic LIFO stack that resizes as needed.
type Stack struct {
    nodes   []*Node
    count   int
}
// Queue is a basic FIFO queue based on a circular list that resizes as needed.
type Queue struct {
    nodes   []*Node
    head    int
    tail    int
    count   int
}

您可以在此操场示例中看到它的运行情况.

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有