从BST删除节点

时间:2016-07-12 21:35:55

标签: java binary-search-tree

我认为除了案例2(删除节点只有一个子树)之外,大部分案例都有效。我的测试用例是下面的树,没有1,2,3和4个节点:enter image description here

这个程序告诉我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);

}

}

2 个答案:

答案 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