1. 二叉树层序遍历与指针连接问题解析
今天我们来解决LeetCode第116题"填充每个节点的下一个右侧节点指针",这是一道考察二叉树层序遍历和指针操作的经典题目。题目要求我们将完美二叉树的每一层节点从左到右用next指针连接起来,最右侧节点的next指针指向NULL。
完美二叉树的特点是所有叶子节点都在同一层,每个父节点都有两个子节点。这种结构特性使得我们可以采用特定的遍历方式来高效解决问题。
1.1 问题核心分析
题目给出的二叉树节点定义如下:
cpp复制class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
};
我们需要填充每个节点的next指针,使其指向同一层的下一个右侧节点。如果当前节点是该层最右侧的节点,则next指针应设为NULL。
例如,给定如下完美二叉树:
code复制 1
/ \
2 3
/ \ / \
4 5 6 7
处理后的next指针连接应为:
code复制 1->NULL
/ \
2->3->NULL
/ \ / \
4->5->6->7->NULL
1.2 解题思路选择
解决这个问题主要有两种思路:
- 层序遍历(BFS):逐层处理节点,连接同一层的相邻节点
- 利用已建立的next指针:通过上层已建立的next指针来连接下层节点
本文将重点讲解第一种方法——基于队列的层序遍历实现,这是最直观且容易理解的解决方案。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基于队列的层序遍历实现
层序遍历(BFS)是解决这个问题的自然选择,因为它能按照层级顺序访问节点,正好符合我们连接同一层节点的需求。
2.1 基础实现框架
我们先来看基础的层序遍历框架:
cpp复制void levelOrder(Node* root) {
if (!root) return;
queue<Node*> q;
q.push(root);
while (!q.empty()) {
int size = q.size();
for (int i = 0; i < size; i++) {
Node* node = q.front();
q.pop();
// 处理当前节点
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
}
}
这个框架已经帮我们完成了按层处理节点的核心逻辑,现在只需要在"处理当前节点"的位置添加next指针的连接逻辑即可。
2.2 next指针连接的关键逻辑
在每一层的遍历中,我们需要:
- 获取当前节点
- 如果不是该层最后一个节点,将其next指向队列中的下一个节点
- 如果是最后一个节点,将其next设为NULL
初始的错误实现可能如下:
cpp复制for (int i = 0; i < size; i++) {
Node* node = q.front();
q.pop();
Node* nextNode = q.front(); // 这里有问题!
if (i == size - 1) {
node->
