Files
leetcode-go/basic/队列实现.md
T

2.6 KiB
Raw Blame History

tags, create time
tags create time
Go
基础数据结构
队列
2026-05-14 18:00

队列(Queue)

什么时候用

看到 BFS、层序遍历、滑动窗口 → 用队列。 FIFO:先进去的先出来。类比排队打饭,先到先得。


模板

type Queue struct {
    data []int // 底层用一个 slice 存数据
}

// Push 入队:往末尾追加一个元素
func (q *Queue) Push(v int) {
    q.data = append(q.data, v)
}

// Pop 出队:取出第一个元素,再把第一个元素切掉
func (q *Queue) Pop() int {
    v := q.data[0]       // 先拿到值
    q.data = q.data[1:]  // 再切除第一个位置
    return v
}

// Front 看队首元素但不取走
func (q *Queue) Front() int {
    return q.data[0]
}

// Empty 判断是否为空
func (q *Queue) Empty() bool {
    return len(q.data) == 0
}

// Len 当前有多少个元素
func (q *Queue) Len() int {
    return len(q.data)
}

核心思路就两件事: append 往尾巴加,data[1:] 从头部踢。简单粗暴有效。


BFS 用法

BFS 的精髓就是:把当前层的节点全部取出,然后把它们的子节点全部放进队列等下一轮处理。

q := &Queue{}
q.Push(root)          // 先把根节点放进去

for !q.Empty() {      // 队列不空就一直处理
    node := q.Front() // 看队首
    q.Pop()           // 弹出队首

    if node.Left != nil {
        q.Push(node.Left)   // 左子节点入队
    }
    if node.Right != nil {
        q.Push(node.Right)  // 右子节点入队
    }
}

如果要按层输出(比如 LeetCode 102),在外层循环里记一下当前层有几个节点,内层只处理这么多:

for !q.Empty() {
    size := q.Len()     // 当前层有几个节点
    level := []int{}    // 存这一层的结果

    for i := 0; i < size; i++ {
        node, _ := q.Pop()
        level = append(level, node.Val)

        if node.Left != nil {
            q.Push(node.Left)
        }
        if node.Right != nil {
            q.Push(node.Right)
        }
    }
    result = append(result, level)  // 这一层处理完了,存起来
}

[!tip] 🔑 关键点

size := q.Len() 这行必须在内层循环前执行。因为内层会不断 Push 新节点进入队列,如果不提前记录当前层的大小,就会无限循环下去。


对应题目

难度 题目 要点
⭐⭐ 102.binary-tree-level-order-traversal 层序遍历标准写法
⭐⭐ 127.word-ladder BFS 求最短路径
⭐⭐⭐ 239.sliding-window-maximum 单调队列(进阶)