题目:
Follow up for problem "Populating Next Right Pointers in Each Node".
What if the given tree could be any binary tree? Would your previous solution still work?
Note:
- You may only use constant extra space.
For example,
Given the following binary tree,
1 / \ 2 3 / \ \ 4 5 7
After calling your function, the tree should look like:
1 -> NULL / \ 2 -> 3 -> NULL / \ \ 4-> 5 -> 7 -> NULL
题意:
填充每个next指针,指向它的下一个右节点。如果没有下一个右节点,则应该将下一个指针设置为toNULL。
最初,所有next指针都设置为toNULL。
解题思路:
这题和populating-next-right-pointers-in-each-node差不多,只是完全二叉树变成了普通二叉树,解法有递归和非递归的。先看看递归的解法。
递归:
思路和上一题的思路差不多,但是这里需要从右结点开始递归。由于二叉树可能有缺陷,所以我们先平行扫描与父节点同层的结点,找到他们的子节点。
代码:
public void connect(TreeLinkNode root) {
if(root == null) {
return;
}
TreeLinkNode temp = root.next;
while(temp !=null) {
if(temp.left != null) {
temp = temp.left;
break;
}else {
if(temp.right !=null) {
temp = temp.right;
break;
}
}
temp = temp.next;
}
if(root.right != null) {
root.right.next = temp;
}
if(root.left != null) {
root.left.next = (root.right != null) ? root.right: temp;
}
connect(root.right);
connect(root.left);
}
非递归的思路:
使用层序遍历
用newLevel 来指向下一层首结点的前一个结点,用curLevel 来遍历这一层
从根节点开始,先判断左结点是否存在,然后curLevel.next连上左结点,然后 遍历,curLevel下移。
右结点与左结点同理
当左右结点都连上之后,root 结点下移
当root 不存在时,表明当前这一层已经遍历完毕,我们需要把root 指向下一层的首结点。同时要把newLevel.next清空,因为不断开的话,当root是叶结点时,那么while循环还会执行,不会进入前两个if,然后root下移赋空之后,会进入最后一个if,之前没有断开dummy->next的话,那么root又指向之前的叶结点了,就产生了死循环了。
最后再将 newLevel 赋给 curLevel,又从下一层开始遍历。
代码:
public void connect(TreeLinkNode root) {
if(root == null ) {
return;
}
TreeLinkNode curLevel = new TreeLinkNode(0);
TreeLinkNode newLevel = curLevel;
while(root != null) {
if(root.left != null) {
curLevel.next = root.left;
curLevel = curLevel.next;
}
if(root.right != null) {
curLevel.next = root.right;
curLevel = curLevel.next;
}
root = root.next;
if(root == null) {
root = newLevel.next;
newLevel.next = null;
curLevel = newLevel;
}
}
}