↕️
选择原则:后进先出用栈,先进先出用队列,总是取最高或最低优先级用堆。三者都在限制“下一个处理谁”。

Stack:后进先出

栈适合 UI 返回、撤销记录、非递归 DFS 和临时解析状态。
PushPopPeek 都是 O(1)。如果撤销操作还需要恢复数据,应把命令或快照压栈,而不只是名称。

Queue:先进先出

队列适合消息缓冲、生成请求、逐帧预算和 BFS:
把大量工作分帧处理能避免单帧尖峰,但要给队列设置最大长度和过载策略,否则生产速度高于消费速度时会持续占用内存。

Queue 实现 BFS

BFS 按层访问,适合最少步数、层级 UI 和邻近扩散。

二叉堆:动态优先级

队列只能保证先来先处理。A* 寻路、AI 调度和定时任务需要反复取最小代价元素,常用二叉最小堆:
插入和弹出都是 O(log n),查看堆顶是 O(1)。Unity 当前运行时配置不一定提供 .NET 的 PriorityQueue<TElement,TPriority>,项目应以实际 API 兼容级别为准。

环形缓冲区

固定容量的网络快照、输入历史和音频采样更适合环形缓冲区:
  • 内存固定,不会无限增长
  • 头尾索引循环复用数组
  • 可选择覆盖最旧数据或拒绝新数据
普通 Queue 更通用;环形缓冲区适合容量明确、追求零扩容的热路径。

复杂度

结构
加入
取出
典型用途
Stack
O(1)
O(1)
撤销、返回、DFS
Queue
O(1)
O(1)
BFS、消息、分帧任务
Binary Heap
O(log n)
O(log n)
A*、调度器、最近目标

常见坑

  • 对空集合直接 PopDequeue
  • 队列无上限,消费者跟不上生产者。
  • 用 List 每次排序模拟优先队列,造成 O(n log n) 重复工作。
  • 堆中优先级变化后不重新调整位置。
  • 在多线程之间共享普通 Stack/Queue 而不做同步。

系列导航

  1. 常用数据结构:Unity/C# 选择指南
  1. Array / List / NativeArray:连续内存容器
  1. Dictionary / HashSet / NativeHashMap:哈希容器
  1. Stack / Queue / Binary Heap:顺序与优先级
  1. 链表:Unity 中何时使用,何时避开
  1. Tree:层级、搜索与决策
  1. Graph:寻路、依赖与关系网络
  1. 空间索引:Grid / Spatial Hash / Quadtree / Octree
  1. Unity Native Containers:Jobs / Burst 下的数据结构

参考资料