【算法--链表】116.填充每个节点的下一个右侧节点指针--通俗讲解
算法通俗讲解推荐阅读
【算法–链表】83.删除排序链表中的重复元素–通俗讲解
【算法–链表】删除排序链表中的重复元素 II–通俗讲解
【算法–链表】86.分割链表–通俗讲解
【算法】92.翻转链表Ⅱ–通俗讲解
【算法–链表】109.有序链表转换二叉搜索树–通俗讲解
【算法–链表】114.二叉树展开为链表–通俗讲解
通俗易懂讲解“填充每个节点的下一个右侧节点指针”算法题目
一、题目是啥?一句话说清
给你一个完美二叉树,填充每个节点的next指针,使其指向同一层的下一个右侧节点;如果没有下一个节点,则设置为NULL。初始时所有next指针为NULL。
示例:
- 输入:root = [1,2,3,4,5,6,7](完美二叉树)
- 输出:[1,#,2,3,#,4,5,6,7,#](其中’#'表示NULL,即节点1的next为NULL,节点2的next指向3,节点4的next指向5,等等)
二、解题核心
利用当前层已经建立的next指针来遍历和连接下一层的节点。 这就像组织一个会议,先安排第一排的人手拉手(通过next指针),然后第一排的人帮助第二排的人手拉手,依次类推,直到所有排都连接起来。
三、关键在哪里?(3个核心点)
想理解并解决这道题,必须抓住以下三个关键点:
1. 利用已建立的next指针
- 是什么:当前层的next指针已经连接好,我们可以用它来遍历当前层,并连接下一层的节点。
- 为什么重要:这样可以避免使用队列等额外数据结构,实现常数空间复杂度。
2. 分层处理
- 是什么:从根节点开始,一层一层地处理,直到叶子层。
- 为什么重要:每层处理完成后,当前层的next指针就完整了,可以用于连接下一层。
3. 连接不同父节点的子节点
- 是什么:对于当前节点的右子节点,需要将其next指针指向当前节点next节点的左子节点(如果存在)。
- 为什么重要:这是连接不同父节点的子节点的关键,确保同一层所有节点都能通过next指针连接。
四、看图理解流程(通俗理解版本)
让我们用完美二叉树 [1,2,3,4,5,6,7] 的例子来可视化过程:
-
初始化:
- 根节点1的next为NULL。
- 设置leftmost指针指向根节点1。
-
处理第一层(根层):
- 当前层只有节点1,没有next节点,所以不需要连接同一层。
- 但需要连接下一层:节点1有左子节点2和右子节点3。
- 将节点2的next指向节点3。
- 由于节点1没有next节点,节点3的next保持NULL。
- 现在第一层处理完成,第二层的next部分连接:2 → 3
-
处理第二层:
- leftmost指针移动到节点2(第二层最左节点)。
- 使用current指针遍历第二层:从节点2开始。
- 节点2有左子节点4和右子节点5:
- 将节点4的next指向节点5。
- 节点2有next节点(节点3),所以将节点5的next指向节点3的左子节点6。
- 移动到节点3:
- 节点3有左子节点6和右子节点7:
- 将节点6的next指向节点7。
- 节点3没有next节点,所以节点7的next保持NULL。
- 节点3有左子节点6和右子节点7:
- 现在第二层处理完成,第三层的next连接完成:4 → 5 → 6 → 7
-
处理第三层:
- leftmost指针移动到节点4。
- 第三层是叶子层,没有子节点,所以不需要连接下一层。
- 遍历第三层,确认next指针已正确设置。
-
结束:所有层的next指针都已填充。
五、C++ 代码实现(附详细注释)
#include <iostream>
using namespace std;// 二叉树节点定义
class