给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL
1. 迭代
从上到下从左到右进行遍历
利用三个指针,start 指向每层的开始节点,cur指向当前遍历的节点,pre指向当前遍历的节点的前一个节点。
如上图,我们需要把 pre 的左孩子的 next 指向右孩子,pre 的右孩子的next指向cur的左孩子
如上图,当 cur 指向 null 以后,我们只需要把 pre 的左孩子的 next 指向右孩子
public Node connect(Node root) {
if (root == null) {
return root;
}
Node pre = root;
Node cur = null;
Node start = pre;
while (pre.left != null) {
//遍历到了最右边的节点,要将 pre 和 cur 更新到下一层,并且用 start 记录
if (cur == null) {
//我们只需要把 pre 的左孩子的 next 指向右孩子。
pre.left.next = pre.right;
pre = start.left;
cur = start.right;
start = pre;
//将下一层的 next 连起来,同时 pre、next 后移
} else {
//把 pre 的左孩子的 next 指向右孩子
pre.left.next = pre.right;
//pre 的右孩子的 next 指向 cur 的左孩子。
pre.right.next = cur.left;
pre = pre.next;
cur = cur.next;
}
}
return root;
}
2. 递归
递归像是一个深度的视角。
以从上往下的方向看,1,2,3,5,6这几个节点在位置上都是紧挨着的,同时这几个节点都是左右串联的
我们以当前节root点为起始,左右节点不断的深入下面,left节点不断往右走,right节点不断往左走,当这两个节点走到底后,整个纵深这段就完成了串联
class Solution {
public Node connect(Node root) {
dfs(root);
return root;
}
void dfs(Node root) {
if(root==null) {
return;
}
Node left = root.left;
Node right = root.right;
//配合动画演示理解这段,以root为起点,将整个纵深这段串联起来
while(left!=null) {
left.next = right;
left = left.right;
right = right.left;
}
//递归的调用左右节点,完成同样的纵深串联
dfs(root.left);
dfs(root.right);
}
}