数组实现层级遍历的核心是利用索引映射父子关系:i的左子为2i+1、右子为2i+2、父为(i-1)/2,通过left/right滑动窗口模拟队列,逐层处理并更新下层索引范围,无需额外内存。

用数组实现层级遍历,核心是把树的逻辑结构“映射”到一维数组上,并借助索引关系模拟队列行为,无需额外申请动态内存或构建链式队列。这种方式特别适合完全二叉树或已知规模的静态树结构,代码轻量、缓存友好、边界清晰。
数组下标隐含父子关系
假设数组 arr 存储节点(索引从 0 开始),对任意有效索引 i:
- 左子节点在 2*i + 1
- 右子节点在 2*i + 2
- 父节点在 (i − 1) / 2(整数除法)
- 数组长度为 size,合法索引范围是 0 到 size−1
这个关系是层级遍历能用数组直接推进的基础——你不需要指针或队列结构,靠算索引就能定位下一层所有节点。
模拟层序遍历:不用队列,只用两个游标
不依赖 queue 或链表,用两个整数变量 left 和 right 维护当前层的起止索引范围:
- 初始时:left = 0,right = 1(根节点单独成层)
- 每轮循环处理区间 [left, right) 内的所有节点
- 同时收集下一层所有非空子节点的索引,更新为新的 left = right,right = next_right
- 当 left ≥ size 时结束
这种“滑动窗口”方式天然分层,每轮输出的就是完整的一层节点值,适合构造二维结果(如 LeetCode 的 levelOrder 返回 [[3],[9,20],[15,7]])。
实战中管理节点变量的关键细节
实际编码时,需注意三个易错点:
-
空节点占位要明确:数组中用
NULL、0或特殊标记(如-1)表示缺失节点,遍历时必须跳过,否则索引计算会错位 -
子节点索引越界检查不能省:计算
2*i+1后,必须判断是否,否则访问非法内存 - 层间衔接靠“批量生成下层索引”:不要边遍历边扩展数组,而是先扫描当前层全部节点,统一记录所有有效子节点位置,再整体移交下一轮
一个可运行的 C 风格伪代码片段
以整型数组为例,输出每层节点值:
void levelOrderFromArr(int* arr, int size) {int left = 0, right = 1;
while (left printf("Level: ");
int next_right = right;
for (int i = left; i if (arr[i] != -1) { // 跳过空占位
printf("%d ", arr[i]);
int l = 2*i + 1, r = 2*i + 2;
if (l if (r }
}
printf("\n");
left = right;
right = next_right;
}
}










