Java算法题-解析填充每个节点的下一个右侧节点指针问题

题目
给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树的定义如下:
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int val) {
this.val = val;
}
public Node(int val, Node left, Node right, Node next) {
this.val = val;
this.left = left;
this.right = right;
this.next = next;
}
}
填充它的每个节点的 next
指针,让这个指针指向其下一个右侧节点。如果找不到右侧节点,则将 next
指针设置为 null
。初始状态下,所有 next
指针都设置为 null
。
引言
填充每个节点的下一个右侧节点指针问题是一个常见的二叉树操作问题,通常用于将同一层的节点连接起来。这个问题可以使用广度优先搜索(BFS)或递归来解决。
算法思路
我们可以使用广度优先搜索(BFS)来解决这个问题。以下是算法的步骤:
- 初始化一个队列,将根节点加入队列。
- 在每一层上,遍历队列中的节点,将每个节点的
next
指针指向队列中下一个节点(即队列中节点的顺序与树中同一层节点的顺序相同)。 - 将当前节点的左子节点和右子节点加入队列。
- 重复步骤2和步骤3,直到队列为空。
代码实现
以下是使用 Java 实现的解决方案:
import java.util.LinkedList;
import java.util.Queue;
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int val) {
this.val = val;
}
public Node(int val, Node left, Node right, Node next) {
this.val = val;
this.left = left;
this.right = right;
this.next = next;
}
}
public class PopulateNextRightPointers {
public Node connect(Node root) {
if (root == null) {
return null;
}
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
Node node = queue.poll();
if (i < size - 1) {
node.next = queue.peek();
}
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
}
return root;
}
}
算法分析
- 时间复杂度:遍历每个节点一次,所以时间复杂度是O(n),其中n是树中的节点数。
- 空间复杂度:使用了一个队列来存储节点,最多存储一层的节点,所以空间复杂度是O(2^h),其中h是树的高度。
示例和测试
假设给定一个示例完美二叉树的根节点 root
,如下所示:
1
/ \
2 3
/ \ / \
4 5 6 7
根据算法,我们可以填充每个节点的 next
指针,让它们指向其下一个右侧节点。我们可以使用以下代码进行测试:
public class Main {
public static void main(String[] args) {
PopulateNextRightPointers solution = new PopulateNextRightPointers();
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
Node result = solution.connect(root);
// 打印每个节点的 `next` 指针
Node node = result;
while (node != null) {
Node levelNode = node;
while (levelNode != null) {
System.out.print(levelNode.val + " ");
levelNode = levelNode.next;
}
System.out.println();
node = node.left;
}
}
}
总结
填充每个节点的下一个右侧节点指针问题是一个常见的二叉树操作问题,通常用于将同一层的节点连接起来。这个问题可以使用广度优先搜索(BFS)来解决,也可以使用递归来解决。这个问题的时间复杂度是O(n),空间复杂度是O(2^h),其中n是树中的节点数,h是树的高度。解决这个问题有助于理解二叉树的遍历和指针操作。