add: 队列算法笔记(Go 语言实现)
Deploy Docs / deploy (push) Successful in 10s

This commit is contained in:
2026-08-26 06:21:01 +00:00
parent 126a26c063
commit b1a29548d2
2 changed files with 289 additions and 0 deletions
+288
View File
@@ -0,0 +1,288 @@
# 队列
!!! note "💡 一句话概述"
队列是一种先进先出(FIFO)的数据结构,只允许从一端入队、另一端出队。
---
## 🔑 核心概念
1. **FIFO 原则**:先入队的元素先出队,类似于排队买票
2. **操作**:入队(Enqueue)从队尾添加,出队(Dequeue)从队头移除
3. **类型**:顺序队列、链式队列、循环队列、双端队列
---
## 📝 详细说明
队列是一种受限的线性表,限制只在表的两端进行操作:
- **队头(Front)**:允许出队的一端
- **队尾(Rear)**:允许入队的一端
**适用场景**:任务调度、消息队列、BFS 遍历、缓冲区、打印队列等。
---
## 💻 代码示例
### 顺序队列(数组实现)
```go
package main
import "fmt"
type Queue struct {
data []int
head int
tail int
size int
}
func NewQueue(capacity int) *Queue {
return &Queue{
data: make([]int, capacity),
head: 0,
tail: 0,
size: capacity,
}
}
func (q *Queue) Enqueue(val int) bool {
if q.tail == q.size {
return false // 队满
}
q.data[q.tail] = val
q.tail++
return true
}
func (q *Queue) Dequeue() (int, bool) {
if q.head == q.tail {
return 0, false // 队空
}
val := q.data[q.head]
q.head++
return val, true
}
func (q *Queue) IsEmpty() bool {
return q.head == q.tail
}
func main() {
q := NewQueue(5)
q.Enqueue(1)
q.Enqueue(2)
q.Enqueue(3)
for !q.IsEmpty() {
val, _ := q.Dequeue()
fmt.Println(val) // 输出: 1 2 3
}
}
```
### 链式队列(链表实现)
```go
package main
import "fmt"
type Node struct {
Val int
Next *Node
}
type LinkedQueue struct {
head *Node
tail *Node
size int
}
func NewLinkedQueue() *LinkedQueue {
return &LinkedQueue{}
}
func (q *LinkedQueue) Enqueue(val int) {
node := &Node{Val: val}
if q.tail != nil {
q.tail.Next = node
}
q.tail = node
if q.head == nil {
q.head = node
}
q.size++
}
func (q *LinkedQueue) Dequeue() (int, bool) {
if q.head == nil {
return 0, false
}
val := q.head.Val
q.head = q.head.Next
if q.head == nil {
q.tail = nil
}
q.size--
return val, true
}
func main() {
q := NewLinkedQueue()
q.Enqueue(10)
q.Enqueue(20)
for {
val, ok := q.Dequeue()
if !ok {
break
}
fmt.Println(val) // 输出: 10 20
}
}
```
### 循环队列
```go
package main
import "fmt"
type CircularQueue struct {
data []int
head int
tail int
size int
cap int
}
func NewCircularQueue(capacity int) *CircularQueue {
return &CircularQueue{
data: make([]int, capacity),
head: 0,
tail: 0,
size: 0,
cap: capacity,
}
}
func (q *CircularQueue) Enqueue(val int) bool {
if q.size == q.cap {
return false
}
q.data[q.tail] = val
q.tail = (q.tail + 1) % q.cap
q.size++
return true
}
func (q *CircularQueue) Dequeue() (int, bool) {
if q.size == 0 {
return 0, false
}
val := q.data[q.head]
q.head = (q.head + 1) % q.cap
q.size--
return val, true
}
func main() {
q := NewCircularQueue(3)
q.Enqueue(1)
q.Enqueue(2)
q.Enqueue(3)
val, _ := q.Dequeue() // 出队 1
fmt.Println("出队:", val)
q.Enqueue(4) // 入队 4
for !q.IsEmpty() {
val, _ := q.Dequeue()
fmt.Println(val) // 输出: 2 3 4
}
}
```
---
## ⚠️ 常见陷阱
!!! warning "顺序队列的假溢出"
用数组实现队列时,即使前面有空位,tail 到达数组末尾也无法入队。解决办法:使用循环队列,通过取模运算让队列"首尾相接"。
!!! warning "队空和队满的判断条件"
循环队列中,`head == tail` 表示队空,`(tail + 1) % cap == head` 表示队满(牺牲一个位置)。或者额外维护一个 `size` 变量来区分。
---
## 🏋️ 练习题
??? question "练习 1:用两个栈实现队列"
使用两个栈实现队列的 push 和 pop 操作。
```go
type MyQueue struct {
inStack []int
outStack []int
}
func (q *MyQueue) Push(x int) {
q.inStack = append(q.inStack, x)
}
func (q *MyQueue) Pop() int {
if len(q.outStack) == 0 {
for len(q.inStack) > 0 {
q.outStack = append(q.outStack, q.inStack[len(q.inStack)-1])
q.inStack = q.inStack[:len(q.inStack)-1]
}
}
val := q.outStack[len(q.outStack)-1]
q.outStack = q.outStack[:len(q.outStack)-1]
return val
}
```
??? question "练习 2:用队列实现 BFS"
用队列实现二叉树的层序遍历。
??? success "答案"
```go
func levelOrder(root *TreeNode) [][]int {
if root == nil {
return nil
}
result := [][]int{}
queue := []*TreeNode{root}
for len(queue) > 0 {
level := []int{}
size := len(queue)
for i := 0; i < size; i++ {
node := queue[0]
queue = queue[1:]
level = append(level, node.Val)
if node.Left != nil {
queue = append(queue, node.Left)
}
if node.Right != nil {
queue = append(queue, node.Right)
}
}
result = append(result, level)
}
return result
}
```
---
## 🔗 相关链接
- [Go container/list](https://pkg.go.dev/container/list) — 标准库双向链表,可用于实现队列
+1
View File
@@ -101,3 +101,4 @@ nav:
- 布谷鸟过滤器: algorithm/cuckoo-filter.md
- HeavyKeeper: algorithm/heavykeeper.md
- 二叉树的遍历: algorithm/binary-tree-traversal.md
- 队列: algorithm/queue.md