📅  最后修改于: 2023-12-03 14:48:57.789000             🧑  作者: Mango
在二叉搜索树(Binary Search Tree,BST)中,每个节点都有一个前驱节点(Inorder Predecessor)和一个后继节点(Inorder Successor)。其中,前驱节点是在二叉树的 Inorder Traversal 中,一个节点的前一个节点,后继节点是 Inorder Traversal 中,一个节点的后一个节点。
在本篇文章中,我们将学习如何为 BST 中的所有节点填充 Inorder Successor。
以下是一种简洁的代码实现方式:
// 向 BST 中插入数据(代码省略)
public static void fillInorderSuccessor(Node root, Node successor) {
if (root == null) {
return;
}
// 遍历左子树
fillInorderSuccessor(root.left, successor);
// 填充当前节点的后继节点
root.inorderSuccessor = successor;
// 设置后继节点为当前节点
successor = root;
// 遍历右子树
fillInorderSuccessor(root.right, successor);
}
我们通过递归遍历二叉搜索树,在 Inorder Traversal 的顺序下依次填充每个节点的 Inorder Successor。具体来说,我们先遍历左子树,由于左子树中所有节点的值都小于根节点,所以我们不需要更新它们的 Inorder Successor。然后,我们将当前节点的 Inorder Successor 设置为前一个节点(即 successor),随后将 successor 设为当前节点,以便后续节点的 Inorder Successor 的更新。最后,我们对右子树执行相似的操作。
这个算法的时间复杂度为 $O(n)$,空间复杂度为 $O(h)$,其中 $n$ 表示 BST 的节点数,$h$ 表示 BST 的高度。
以下是一个基于 BST 的完整示例:
class Node {
int val;
Node left, right, inorderSuccessor;
Node(int val) {
this.val = val;
this.left = this.right = this.inorderSuccessor = null;
}
}
public class Main {
public static void main(String[] args) {
// 构建 BST
Node root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
// 为 BST 的所有节点填充 Inorder Successor
fillInorderSuccessor(root, null);
// 遍历 BST,打印每个节点及其 Inorder Successor
Node current = root.left.right.left;
while (current != null) {
System.out.print(current.val + ": ");
if (current.inorderSuccessor != null) {
System.out.println(current.inorderSuccessor.val);
} else {
System.out.println("null");
}
current = current.inorderSuccessor;
}
}
public static void fillInorderSuccessor(Node root, Node successor) {
if (root == null) {
return;
}
fillInorderSuccessor(root.left, successor);
root.inorderSuccessor = successor;
successor = root;
fillInorderSuccessor(root.right, successor);
}
}
在上述示例中,我们先构建了一个 BST,然后为所有节点填充了 Inorder Successor,最后遍历 BST 并打印每个节点的 Inorder Successor。
我们学习了如何为 BST 中的所有节点填充 Inorder Successor。这个算法的实现简单,时间复杂度为 $O(n)$,是解决该问题的最优解法。