101 lines
2.0 KiB
Go
101 lines
2.0 KiB
Go
package ds
|
|
|
|
// ds-deque.go
|
|
// 泛型双端队列,基于环形缓冲。PushFront/PushBack/PopFront/PopBack 全 O(1) 均摊。
|
|
// 当容量不足时扩容为 2 倍,自动重新对齐。
|
|
|
|
// Deque 双端队列,零值可用。
|
|
type Deque[T any] struct {
|
|
buf []T
|
|
head int // 队首索引,逆时针(向后)增长
|
|
tail int // 队尾索引 +1
|
|
n int // 元素个数
|
|
}
|
|
|
|
// Len 元素个数。
|
|
func (d *Deque[T]) Len() int { return d.n }
|
|
|
|
// Empty 是否为空。
|
|
func (d *Deque[T]) Empty() bool { return d.n == 0 }
|
|
|
|
// PushBack 尾部插入。
|
|
func (d *Deque[T]) PushBack(v T) {
|
|
d.grow()
|
|
d.buf[d.tail] = v
|
|
d.tail = (d.tail + 1) % len(d.buf)
|
|
d.n++
|
|
}
|
|
|
|
// PushFront 头部插入。
|
|
func (d *Deque[T]) PushFront(v T) {
|
|
d.grow()
|
|
d.head = (d.head - 1 + len(d.buf)) % len(d.buf)
|
|
d.buf[d.head] = v
|
|
d.n++
|
|
}
|
|
|
|
// PopBack 尾部弹出;空返回零值和 false。
|
|
func (d *Deque[T]) PopBack() (T, bool) {
|
|
var zero T
|
|
if d.n == 0 {
|
|
return zero, false
|
|
}
|
|
d.tail = (d.tail - 1 + len(d.buf)) % len(d.buf)
|
|
v := d.buf[d.tail]
|
|
d.buf[d.tail] = zero
|
|
d.n--
|
|
return v, true
|
|
}
|
|
|
|
// PopFront 头部弹出;空返回零值和 false。
|
|
func (d *Deque[T]) PopFront() (T, bool) {
|
|
var zero T
|
|
if d.n == 0 {
|
|
return zero, false
|
|
}
|
|
v := d.buf[d.head]
|
|
d.buf[d.head] = zero
|
|
d.head = (d.head + 1) % len(d.buf)
|
|
d.n--
|
|
return v, true
|
|
}
|
|
|
|
// Front 查看头部,不移除。
|
|
func (d *Deque[T]) Front() (T, bool) {
|
|
var zero T
|
|
if d.n == 0 {
|
|
return zero, false
|
|
}
|
|
return d.buf[d.head], true
|
|
}
|
|
|
|
// Back 查看尾部,不移除。
|
|
func (d *Deque[T]) Back() (T, bool) {
|
|
var zero T
|
|
if d.n == 0 {
|
|
return zero, false
|
|
}
|
|
return d.buf[(d.tail-1+len(d.buf))%len(d.buf)], true
|
|
}
|
|
|
|
// grow 容量不足时扩容并重新对齐。
|
|
func (d *Deque[T]) grow() {
|
|
if d.buf == nil {
|
|
d.buf = make([]T, 8)
|
|
return
|
|
}
|
|
if d.n < len(d.buf) {
|
|
return
|
|
}
|
|
oldCap := len(d.buf)
|
|
newCap := oldCap * 2
|
|
nb := make([]T, newCap)
|
|
// 把 head..head+n 的环形数据复制到新缓冲区前端。
|
|
for i := 0; i < d.n; i++ {
|
|
nb[i] = d.buf[(d.head+i)%oldCap]
|
|
}
|
|
d.buf = nb
|
|
d.head = 0
|
|
d.tail = d.n
|
|
}
|