给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

  1. struct Node {
  2. int val;
  3. Node *left;
  4. Node *right;
  5. Node *next;
  6. }

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。

image.png

参考前序遍历二叉树的实现

  1. public static TreeNode connectNode(TreeNode node) {
  2. // 递归的结束条件
  3. if (node == null || node.left == null) {
  4. // 终止时处理办法
  5. return null;
  6. }
  7. // 当前节点需要做的事情
  8. nodeNeedTodo(node);
  9. // 让当前节点的左子节点重复当前节点
  10. connectNode(node.left);
  11. // 让当前节点的右子节点重复当前节点
  12. connectNode(node.right);
  13. return node;
  14. }
  15. /**
  16. * 让左子节点指向右子节点
  17. */
  18. private static void nodeNeedTodo(TreeNode node) {
  19. node.left.next = node.right;
  20. }

测试验证

  1. public static void main(String[] args) {
  2. Integer[] arr = {4,2,7,1,3,6,9};
  3. TreeNode root = BinaryTreeUtil.arrToTree(arr);
  4. root = connectNode(root);
  5. BinaryTreeUtil.levelOrderPrintNext(root);
  6. }
  1. 4-->null 2-->7 7-->null 1-->3 3-->null 6-->9 9-->null

正确的节点需要做的事

  1. private static void nodeNeedTodo(TreeNode node1, TreeNode node2) {
  2. node1.next = node2
  3. }

正确的算法

  1. public static TreeNode connectNode(TreeNode node) {
  2. if (node == null) {
  3. return null;
  4. }
  5. connectNode(node.left, node.right);
  6. return node;
  7. }
  8. private static void connectNode(TreeNode node1, TreeNode node2) {
  9. if (node1 == null || node2 == null) {
  10. return;
  11. }
  12. // 需要节点做的事情
  13. nodeNeedTodo(node1, node2);
  14. // 相同父节点
  15. // 左子树的左子节点指向右子节点
  16. connectNode(node1.left, node1.right);
  17. // 右子树的左子节点指向右子节点
  18. connectNode(node2.left, node2.right);
  19. // 跨父节点
  20. // 左子树的右子节点指向右子树的左子节点
  21. connectNode(node1.right, node2.left);
  22. }

测试验证

  1. public static void main(String[] args) {
  2. Integer[] arr = {4,2,7,1,3,6,9};
  3. TreeNode root = BinaryTreeUtil.arrToTree(arr);
  4. root = connectNode(root);
  5. BinaryTreeUtil.levelOrderPrintNext(root);
  6. }
  1. 4-->null 2-->7 7-->null 1-->3 3-->6 6-->9 9-->null

树节点对象

  1. public class TreeNode {
  2. int val;
  3. TreeNode left;
  4. TreeNode right;
  5. TreeNode next;
  6. TreeNode(){}
  7. TreeNode(int val) {this.val = val;}
  8. TreeNode(int val, TreeNode left, TreeNode right) {
  9. this.val = val;
  10. this.left = left;
  11. this.right = right;
  12. }
  13. }

辅助工具类

  1. /**
  2. * 层序遍历打印
  3. * @param node
  4. */
  5. public static void levelOrderPrintNext(TreeNode node) {
  6. if (node == null) {
  7. return;
  8. }
  9. LinkedList<TreeNode> linkedList = new LinkedList<>();
  10. linkedList.add(node);
  11. while (!linkedList.isEmpty()) {
  12. TreeNode temp = linkedList.remove();
  13. if (temp.next == null) {
  14. System.out.print(temp.val + "-->" + temp.next + " ");
  15. } else {
  16. System.out.print(temp.val + "-->" + temp.next.val + " ");
  17. }
  18. if (temp.left != null) {
  19. linkedList.add(temp.left);
  20. }
  21. if (temp.right != null) {
  22. linkedList.add(temp.right);
  23. }
  24. }
  25. }