我认为除了案例2(删除节点只有一个子树)之外,大部分案例都有效。我的测试用例是下面的树,没有1,2,3和4个节点:
这个程序告诉我6从树中删除但是当我尝试打印树时,它仍然显示6在树中。
public class RandomNode {
static int size;
public static class Node {
int data;
Node left;
Node right;
public Node(int data) {
this.data = data;
left = null;
right = null;
size++;
}
}
// delete node in right subtree
public Node delete(Node root, int data) {
// base case - if tree is empty
if (root == null)
return root;
// search for deletion node
else if (data < root.data)
root.left = delete(root.left, data);
else if (data > root.data) {
root.right = delete(root.right, data);
} else {
// case 1: deletion node has no subtrees
if (root.left == null && root.right == null) {
root = null;
size--;
System.out.println(data + " successfully deleted from tree (case1)");
// case 2: deletion node has only one subtree
} else if (root.left != null && root.right == null) {
root = root.left;
size--;
System.out.println(data + " successfully deleted from tree (case2a)");
} else if (root.left == null && root.right != null) {
root = root.left;
size--;
System.out.println(data + " successfully deleted from tree (case2b)");
// case 3: deletion node has two subtrees
// *find min value in right subtree
// *replace deletion node with min value
// *remove the min value from right subtree or else there'll be
// a duplicate
} else if (root.left != null && root.right != null) {
Node temp;
if (root.right.right == null && root.right.left == null)
temp = findMinNode(root.left);
else
temp = findMinNode(root.right);
System.out.println(root.data + " replaced with " + temp.data);
root.data = temp.data;
if (root.right.right == null || root.left.left == null)
root.left = delete(root.left, root.data);
else
root.right = delete(root.right, root.data);
size--;
System.out.println(temp.data + " succesfuly deleted from tree (case3)");
}
}
return root;
}
// find min value in tree
public Node findMinNode(Node root) {
while (root.left != null)
root = root.left;
System.out.println("min value: " + root.data);
return root;
}
public void preOrderTraversal(Node root) {
if (root == null)
return;
preOrderTraversal(root.left);
System.out.println(root.data);
preOrderTraversal(root.right);
}
public static void main(String[] args) {
RandomNode r = new RandomNode();
Node root = new Node(6);
//root.left = new Node(2);
root.right = new Node(9);
//root.left.left = new Node(1);
//root.left.right = new Node(5);
//root.left.right.left = new Node(4);
//root.left.right.left.left = new Node(3);
root.right.left = new Node(8);
root.right.right = new Node(13);
root.right.left.left = new Node(7);
root.right.right.left = new Node(11);
root.right.right.right = new Node(18);
r.delete(root, 6);
r.preOrderTraversal(root);
}
}
答案 0 :(得分:2)
当你做root = root.left;和大小 - 你还必须使root.left = null。
这里你只是将root作为root.left而不是将root.left设为null。
答案 1 :(得分:1)
因为我在功能上写它所以我很难遵循 然而,
if (root.right.right == null || root.left.left == null)
root.left = delete(root.left, root.data);
else
root.right = delete(root.right, root.data);
可能是错的,因为它应该反映您之前的findMinNode()
次调用,因此应该是
if(root.right.right == null && root.right.left == null)
root.left = delete(root.left, root.data);
调试时有更多错误。
首先,java是按值传递的,所以如果你要删除顶级节点(root),你的指针也应该更新。因此,呼叫应为root = r.delete(root, 6);
其次,还有另一个错误。情况2a将root分配给root.left ...为null。它应该是root.right。
完成这些更改后,输出变为:
6 successfully deleted from tree (case2b)
7
8
9
11
13
18