60 lines
1.3 KiB
Go
60 lines
1.3 KiB
Go
package ds
|
|
|
|
// ds-queue.go
|
|
// 泛型切片队列。Enqueue O(1) 均摊,Dequeue O(1)(用 head 指针,避免每次头部搬运)。
|
|
// 当剩余元素不足时惰性整理底层数组,控制内存增长。
|
|
|
|
// Queue 泛型队列,零值可用。
|
|
type Queue[T any] struct {
|
|
data []T
|
|
head int // 队首索引,避免 O(n) 头部搬运
|
|
}
|
|
|
|
// Enqueue 入队。
|
|
func (q *Queue[T]) Enqueue(v T) {
|
|
q.data = append(q.data, v)
|
|
}
|
|
|
|
// Dequeue 出队;空队列返回零值和 false。
|
|
func (q *Queue[T]) Dequeue() (T, bool) {
|
|
var zero T
|
|
if q.head >= len(q.data) {
|
|
return zero, false
|
|
}
|
|
v := q.data[q.head]
|
|
q.data[q.head] = zero // 置零,释放引用
|
|
q.head++
|
|
// 当已出队部分超过总容量一半时,整理切片回收底层内存。
|
|
if q.head > 0 && q.head*2 >= cap(q.data) {
|
|
q.compact()
|
|
}
|
|
return v, true
|
|
}
|
|
|
|
// Front 查看队首,不移除。
|
|
func (q *Queue[T]) Front() (T, bool) {
|
|
var zero T
|
|
if q.head >= len(q.data) {
|
|
return zero, false
|
|
}
|
|
return q.data[q.head], true
|
|
}
|
|
|
|
// Len 队列元素个数。
|
|
func (q *Queue[T]) Len() int { return len(q.data) - q.head }
|
|
|
|
// Empty 是否为空。
|
|
func (q *Queue[T]) Empty() bool { return q.head >= len(q.data) }
|
|
|
|
// compact 回收已出队占用的底层内存。
|
|
func (q *Queue[T]) compact() {
|
|
n := q.Len()
|
|
if n == 0 {
|
|
q.data = q.data[:0]
|
|
} else {
|
|
copy(q.data, q.data[q.head:])
|
|
q.data = q.data[:n]
|
|
}
|
|
q.head = 0
|
|
}
|