题目

给定一个二叉树,其节点结构如下:

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

引言

填充每个节点的下一个右侧节点指针问题是一个常见的二叉树操作问题,通常用于将同一层的节点连接起来。这个问题可以使用递归来解决。

算法思路

我们可以使用递归来解决这个问题。以下是算法的步骤:

  1. 从根节点开始,遍历每一层的节点,连接同一层的节点。
  2. 对于每个节点,首先连接其左子节点和右子节点。这可以通过 node.left.next = node.right 来实现。
  3. 接下来,连接其右子节点和同一层的下一个节点的左子节点。这可以通过 node.right.next = node.next.left 来实现,其中 node.next 表示 node 的父节点的 next 指针。
  4. 递归调用同样的操作,连接下一层的节点。

代码实现

以下是使用 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;
    }
}

public class PopulateNextRightPointersII {
    public Node connect(Node root) {
        if (root == null) {
            return null;
        }

        connectNodes(root.left, root.right);
        return root;
    }

    private void connectNodes(Node node1, Node node2) {
        if (node1 == null || node2 == null) {
            return;
        }

        // 连接当前层的两个节点
        node1.next = node2;

        // 连接左子节点的右子节点和右子节点的左子节点
        connectNodes(node1.left, node1.right);
        connectNodes(node2.left, node2.right);

        // 连接跨越当前节点的两个子树
        connectNodes(node1.right, node2.left);
    }
}

算法分析

  • 时间复杂度:遍历每个节点一次,所以时间复杂度是O(n),其中n是树中的节点数。
  • 空间复杂度:递归调用栈的深度最多为树的高度,所以空间复杂度是O(h),其中h是树的高度。

示例和测试

假设给定一个示例二叉树的根节点 root,如下所示:

        1
       / \
      2   3
     / \   \
    4  5   7

根据算法,我们可以填充每个节点的 next 指针,让它们指向其下一个右侧节点。我们可以使用以下代码进行测试:

public class Main {
    public static void main(String[] args) {
        PopulateNextRightPointersII solution = new PopulateNextRightPointersII();
        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.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;
        }
    }
}

总结

填充每个节点的下一个右侧节点指针问题是一个常见的二叉树操作问题,通常用于将同一层的节点连接起来。这个问题可以使用递归来解决,通过递归遍历每一层的节点并连接它们的 next 指针。这个问题的时间复杂度是O(n),空间复杂度是O(h),其中n是树中的节点数,h是树的高度。解决这个问题有助于理解递归在二叉树操作中的应用。

标签: 编程算法, 编程算法题, 编程算法大全, 编程算法流程, 算法设计与分析, 数据结构与算法, 算法优化, 算法实现, 常见编程算法, 编程算法入门, 编程算法进阶, 编程算法精通