Текущая библиотека Go не предоставляет контейнер очереди. Чтобы реализовать простую очередь, я использую кругный массив в качестве базовой структуры данных. Отсюда следует алгоритмы, указанные в TAOCP:Как реализовать очередь в Go?
Insert Y into queue X: X[R]<-Y; R<-(R+1)%M; if R=F then OVERFLOW.
Delete Y from queue X: if F=R then UNDERFLOW; Y<-X[F]; F<-(F+1) % M.
F: Front, R: Rear, M: Array length.
Ниже приводится код:
package main
import (
"fmt"
)
type Queue struct {
len int
head, tail int
q []int
}
func New(n int) *Queue {
return &Queue{n, 0, 0, make([]int, n)}
}
func (p *Queue) Enqueue(x int) bool {
p.q[p.tail] = x
p.tail = (p.tail + 1) % p.len
return p.head != p.tail
}
func (p *Queue) Dequeue() (int, bool) {
if p.head == p.tail {
return 0, false
}
x := p.q[p.head]
p.head = (p.head + 1) % p.len
return x, true
}
func main() {
q := New(10)
for i := 1; i < 13; i++ {
fmt.Println(i, q.Enqueue(i))
}
fmt.Println()
for i := 1; i < 13; i++ {
fmt.Println(q.Dequeue())
}
}
Но выход, очевидно, неправильно:
1 истинный 2 истинный 3 истинный 4 истинный 5 true 6 true 7 true true 9 истинный 10 ложного 11 истинно 12 истинно
11 истинно 12 истинны 0 ложных 0 ложных 0 ложных 0 ложных 0 ложных 0 ложных 0 ложных 0 ложных 0 ложных 0 ложных
Я думаю, мне нужно еще одно поле, чтобы код работал правильно. Что вы предлагаете?
Усовершенствованный код имеет небольшой недостаток: массив размером n может содержать только n-1 элементов.
package main
import (
"fmt"
)
type Queue struct {
len int
head, tail int
q []int
}
func New(n int) *Queue {
return &Queue{n, 0, 0, make([]int, n)}
}
func (p *Queue) Enqueue(x int) bool {
p.q[p.tail] = x
ntail := (p.tail + 1) % p.len
ok := false
if ntail != p.head {
p.tail = ntail
ok = true
}
return ok
}
func (p *Queue) Dequeue() (int, bool) {
if p.head == p.tail {
return 0, false
}
x := p.q[p.head]
p.head = (p.head + 1) % p.len
return x, true
}
func main() {
q := New(10)
for i := 1; i < 13; i++ {
fmt.Println(i, q.Enqueue(i))
}
fmt.Println()
for i := 1; i < 13; i++ {
fmt.Println(q.Dequeue())
}
}
Теперь вам это не нужно: http://stackoverflow.com/a/31127526/1090562 –