编写一个JAVA 程序,分别按下列方法在二叉查找树上做情形3(即被删除的节点,左、右子树均非空)的删除: a. 用 中最大节点 来代替,递归地删除 ; b. 交替在用 中最大的节点以及 中最小的节点来代替,并递归在删除适当的节点; c. 随机地选用 中最大的节点及 中最小的节点来代替(递归地删除适当的节点)。 哪种方法具有最好的平衡性?哪种在处理整个操作序列过程中花费最少的CPU时间?
时间: 2024-02-25 08:54:03 浏览: 30
以下是分别按照三种方法实现情形3删除的JAVA程序:
```java
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class BST {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) return null;
if (key < root.val) {
root.left = deleteNode(root.left, key);
} else if (key > root.val) {
root.right = deleteNode(root.right, key);
} else {
if (root.left == null) {
return root.right;
} else if (root.right == null) {
return root.left;
} else {
// 方法1:使用中序遍历的前驱节点
TreeNode maxNode = getMax(root.left);
root.val = maxNode.val;
root.left = deleteNode(root.left, root.val);
// 方法2:交替使用中序遍历的前驱和后继节点
// TreeNode minNode = getMin(root.right);
// root.val = minNode.val;
// root.right = deleteNode(root.right, root.val);
// 方法3:随机使用中序遍历的前驱和后继节点
// int rand = (int) (Math.random() * 2);
// if (rand == 0) {
// TreeNode maxNode = getMax(root.left);
// root.val = maxNode.val;
// root.left = deleteNode(root.left, root.val);
// } else {
// TreeNode minNode = getMin(root.right);
// root.val = minNode.val;
// root.right = deleteNode(root.right, root.val);
// }
}
}
return root;
}
private TreeNode getMax(TreeNode node) {
while (node.right != null) node = node.right;
return node;
}
private TreeNode getMin(TreeNode node) {
while (node.left != null) node = node.left;
return node;
}
}
```
在情形3的删除中,使用中序遍历的前驱或后继节点来代替被删除节点可以保证二叉查找树的平衡性。但是,不同的方法在处理整个操作序列过程中花费的CPU时间可能会有所不同。
方法1使用中序遍历的前驱节点,可以保证删除后的树的高度不会增加,因此具有最好的平衡性;方法2和方法3则会交替使用前驱和后继节点,可能导致树的高度增加,因此平衡性不如方法1。
在处理整个操作序列过程中花费的CPU时间,三种方法的差异取决于随机选择前驱或后继节点的概率。如果随机选择的概率接近于0.5,则方法3的平均时间复杂度最小;否则,方法1和方法2的平均时间复杂度会更小。