当前位置: 首页 > 知识库问答 >
问题:

二叉搜索树删除节点函数未删除

萧德庸
2023-03-14

我的删除方法由4个if语句组成,用于处理二叉查找树中的4种不同类型的删除。不确定哪里错了,但当我检查它时,它没有删除任何节点。如果赞赏,任何帮助。提前感谢'

我怀疑问题在于我试图将节点删除替换为空

public class BinaryTree<T extends Comparable<T>> {

private class Node{

    private T data;
    private Node left;
    private Node right;


    // left and right child do not have to nessary exist
    public Node ( T data) {
        this.data = data;
        this.left = null;
        this.right = null;
    }}

    private Node root;
    private int count = 0;

    public void add( T data) {
        if ( isEmpty()) {
            root = new Node(data);
            count++;
        }
        else {
            insert(data, root);
            count++;
        }
    }

    public boolean isEmpty() { 
        return root == null;
    }

    public T getRoot()  {
        if ( root.data == null) {
            System.out.println("Root is empty");
            return null;
        }
        else {
        return  root.data;
    }}

    public Node getRootNode() {
        return root;
    }

    /*
     * Checking if the data is larger or lesser than the parent's data
     * If the data is smaller than the parent's data, node.left is created
     * If the data is bigger than the parent's data, node.right is created
     */
    private void insert( T data, Node node) {

        /*
         * If 1st obj is less than the 2nd obj return a neg
         * if 1st obj is more than the 2nd obj return a pos
         * if equal return 0
         */
        int compare = data.compareTo(node.data);
        if ( compare < 1 ){
            if (node.left == null ) {
                node.left = new Node(data);

            }

        // make node.left if it is filled  
            else {
                insert(data, node.left);
            }
        }

        else {
            if ( node.right == null) {
                node.right = new Node(data);
            }
            else {
                insert( data, node.right);
            }
        }
    }

    public int getSize() {
        return count;
    }

    public boolean search ( T data) {

        Node temp = searchInner(data, root);
        if ( temp.data == data) {
            System.out.println(temp.data);
            return true;
        }
        else {
            return false;
        }

    }


    public Node searchInner( T data, Node node) {

        int compare = data.compareTo(node.data);

        if ( getRoot() == data ) {
            return root;
        }

        if ( compare > 0) {
            return searchInner( data, node.right);  
        }

        if ( compare < 0 ) {
            return searchInner(data , node.left);
        }

        if ( compare == 0 ) {
            return node;
        }

        else {
            System.out.println("Not found");
            return node;
        }

    }

    public void remove( T data) {
        remove1( root, data);
    }

    private Node remove1( Node node1, T data) {

        Node parent = root;
        Node node = root;
        Node temp;
        boolean isLeft = true;

        while ( node.data != data) {

            parent = node;

            if ( isEmpty()) {
                System.out.println("Unable to remove, root is empty");
                break;
            }

            if ( compare(data, node.data) < 0) {
                node = node.left;
                isLeft = true;
            }

            if ( compare(data, node.data) > 0) {
                node = node.right;
                isLeft = false;
            }

            else {
                // remove node if left child available
                if ( node.left == null && node.right != null) {

                    if ( isLeft) {
                        parent.left = node.right;
                    }

                    else {
                        parent.right = node.right;
                    }
                    count --;
                    break;
                }

                //remove node if right child available
                if ( node.right == null && node.left != null) {

                    if ( isLeft) {
                        parent.left = node.left;
                    }

                    else {
                        parent.right = node.left;
                    }
                    count --;
                    break;
                }

                // Remove node if 2 child available
                if ( node.left != null && node.right != null ) {

                    node = min(node.right);
                    node.right = remove1(node.right, node.data);

                }

                // remove node if no child available
                 if ( node.left == null && node.right == null) {
                    if (  isLeft ) {
                        parent.left = null;
                    }
                    else {
                        parent.right = null;
                    }
                    count --;
                    break;
                }

            }


        }
            return node;   
        }

    // fine the smallest node in the right subtree
    private Node min ( Node node1 ) {
        while ( node1.left != null) {
            node1 = node1.left;
        }
        return node1;
    }

    private int compare( T data, T data1) {
        return data.compareTo(data1);
    }

    public void printBST(T data) {
        printTree( root, data);
    }

    private void printTree( Node node, T data)
     {
        if(node == null) return;

        System.out.println(data + " + " + node.data);
        printTree(node.left , data);
        printTree(node.right , data);
     }

    public int getHeight() {
        return height(root);
    }

    private int height( Node node) {

        if  (node == null) return 0;
        else
            return 1 + Math.max(height(node.left), height(node.right));
        }

    public void print() {
        println(root);
    }

    private void println ( Node node) {

        LinkedList<T> q = new LinkedList<T>();
        q.add(node.data);

        if ( node == null) {
            return;
        }

        int size = getSize();
        while ( size > 0) {

                System.out.print(q);

            q.clear();
            if ( node.left != null) {
                q.add(node.left.data);
                size --;
            }
            if ( node.right != null) {
                q.add(node.right.data);
                size --;
            }
            if ( node.right != null&& node.left != null) {
                System.out.println();
            }
            if ( size > 1) {
                System.out.println(",");
            }
        }

    }

    public boolean sameTree( Node root1, Node root2) {

        if ( root1 == null && root2 == null) {
            return true;
        }

        if ( root1 != null && root2 != null) {
            return  root1.data == root2.data && sameTree(root1.left,root2.left) && sameTree(root1.right, root2.right);
        }
        else {
            return false;
        }
    }

}

共有1个答案

晏炳
2023-03-14

我重写了您的BinaryTree类。我添加了一个新的删除方法,它使用您的min(Node node)方法和我创建的其他方法,它只删除树的最小元素。此外,我还通过添加新的构造函数和添加BinaryTree类中的size变量来修改您的Node类我修改了所有这些,以使方法删除()正常工作


import java.util.LinkedList;

public class BinaryTree<T extends Comparable<T>> {

    private class Node<T> { //Here we specify what the node contains

        private T data;
        private Node<T> left;
        private Node<T> right;
        private int size;

        public Node(T value) {
            this(value, null, null);
        }

        // left and right child do not have to nessary exist
        public Node(T data, Node<T> left, Node<T> right) {
            this.data = data;
            this.left = null;
            this.right = null;
            size = 1;
            if (left != null) {
                size += left.size;
            }
            if (right != null) {
                size += right.size;
            }
        }
    }
    private Node root;

    public BinaryTree() { //Added a constructor to set the root node to null
        root = null;
    }

    public boolean isEmpty() {
        return root == null;
    }

    public T getRootData() { //Changed the name to other more clear
        if (root.data == null) {
            System.out.println("Root is empty");
            return null;
        } else {
            return (T) root.data;
        }
    }

    public Node getRootNode() {
        return root;
    }

    public void insert(T x) { //The new insert method
        root = insert(x, root);
    }

    protected Node<T> insert(T x, Node<T> actual) {
        //We check if the node exists, in case not we just create a new node
        if (actual == null) {
            return new Node<T>(x);
        }
        int cmp = compare(x, actual.data);
        if (cmp < 0) {
            actual.left = insert(x, actual.left);
        } else if (cmp > 0) {
            actual.right = insert(x, actual.right);
        } else {
            // If the node exists we just update his content
            actual.data = x;
        }
        actual.size = 1 + getSize(actual.left) + getSize(actual.right);
        return actual;
    }

     public int getSize() { //New method
        return getSize(root);
    }

    private int getSize(Node<T> actual) {
        if (actual == null) {
            return 0;
        } else {
            return actual.size;
        }
    }

    public boolean search(T data) {

        Node temp = searchInner(data, root);
        if (temp.data == data) {
            System.out.println(temp.data);
            return true;
        } else {
            return false;
        }

    }

    public Node searchInner(T data, Node node) {

        int compare = data.compareTo((T) node.data);

        if (getRootData() == data) {
            return root;
        }

        if (compare > 0) {
            return searchInner(data, node.right);
        }

        if (compare < 0) {
            return searchInner(data, node.left);
        }

        if (compare == 0) {
            return node;
        } else {
            System.out.println("Not found");
            return node;
        }

    }

    public void remove(T data) {

        remove1(root, data);
    }

    private Node remove1(Node actual, T data) {
        if (actual == null) {
            return actual;
        }
        int cmp = compare(data, (T) actual.data);
        //Check whether the value is lesser greater or equal than the one we are just visiting
        if (cmp < 0) {
            actual.left = remove1(actual.left, data);
        } else if (cmp > 0) {
            actual.right = remove1(actual.right, data);
        } else {
            if (actual.right == null) {
                return actual.left;
            }
            if (actual.left == null) {
                return actual.right;
            }
            actual.data = min(actual.right).data;
            actual.right = removeMin(actual.right);
        }
        return actual;
    }

    public Node removeMin() {
        //A new method to remove the minimum element
        Node min = min(root);
        root = removeMin(root);
        return min;
    }

    private Node removeMin(Node actual) {
        if (actual.left == null) {
            return actual.right;
        }
        actual.left = removeMin(actual.left);
        actual.size--;
        return actual;
    }

    // fine the smallest node in the right subtree
    private Node min(Node node1) {
        while (node1.left != null) {
            node1 = node1.left;
        }
        return node1;
    }

    private int compare(T data, T data1) {
        return data.compareTo(data1);
    }

    public void printBST(T data) {
        printTree(root, data);
    }

    private void printTree(Node node, T data) {
        if (node == null) {
            return;
        }

        System.out.println(data + " + " + node.data);
        printTree(node.left, data);
        printTree(node.right, data);
    }

    public int getHeight() {
        return height(root);
    }

    private int height(Node node) {

        if (node == null) {
            return 0;
        } else {
            return 1 + Math.max(height(node.left), height(node.right));
        }
    }

    public void print() {
        println(root);
    }

    private void println(Node node) {

        LinkedList<T> q = new LinkedList<T>();
        q.add((T) node.data);

        if (node == null) {
            return;
        }

        int size = getSize();
        while (size > 0) {

            System.out.print(q);

            q.clear();
            if (node.left != null) {
                q.add((T) node.left.data);
                size--;
            }
            if (node.right != null) {
                q.add((T) node.right.data);
                size--;
            }
            if (node.right != null && node.left != null) {
                System.out.println();
            }
            if (size > 1) {
                System.out.println(",");
            }
        }

    }

    public boolean sameTree(Node root1, Node root2) {

        if (root1 == null && root2 == null) {
            return true;
        }

        if (root1 != null && root2 != null) {
            return root1.data == root2.data && sameTree(root1.left, root2.left) && sameTree(root1.right, root2.right);
        } else {
            return false;
        }

    }
}

我希望这对你有帮助

 类似资料:
  • 在二元搜索树的情况下,为什么我们不能简单地在一个节点有两个子节点的情况下,将一个节点的前一个节点替换为后一个节点?

  • 当删除具有两个子节点的节点时,如果指示使用标准的二叉搜索树节点删除算法,我们应该将其替换为右子树的最小节点还是左子树的最大节点?

  • 我正在为二元搜索树组装函数,结果遇到了麻烦。我正在研究当需要从树中删除包含指定值的节点时可能遇到的每种情况。如果节点没有左右子节点,我不确定如何处理释放节点。函数必须返回节点。我是否备份、检查每个左、右子级,并在子级中删除该值?但是如果该值在根中,我是否会遇到类似的问题,即如何删除它?作为解释,程序使用一个void指针,然后在一个单独的函数compare()中强制转换类型val,该函数计算两个值并

  • 主要内容:src/runoob/binary/BSTRemove.java 文件代码:本小节介绍二分搜索树节点的删除之前,先介绍如何查找最小值和最大值,以及删除最小值和最大值。 以最小值为例(最大值同理): 查找最小 key 值代码逻辑,往左子节点递归查找下去: ... // 返回以node为根的二分搜索树的最小键值所在的节点 private Node minimum (Node node ) {     if ( node. left == null )         retu

  • 我正在尝试从二叉查找树中删除节点。我可以成功地删除树上的任何其他节点,除了一个特殊的情况。如果目标节点有两个子节点,左边的子节点有右边的子树,我可以定位正确的替换节点,并将值切换到目标节点,但替换节点永远不会被删除。 看看上面的图片,如果我尝试删除17,程序将正确地导航到13,并用13替换17,但它不会像预期的那样删除原来的13。 我附加了我的remove方法和其中引用的方法。 这是我的Node类

  • 目前,我在理解如何在没有传递节点时从二进制搜索树中删除节点时遇到了一个问题。我有两个类,BSTSet和BSTNode,每个类都有一个remove方法。。 当我被传递一个节点时,我理解删除方法,但当我在根上调用remove方法并试图从node类中删除节点时,我不知道从何处开始。有人能告诉我吗?谢谢如果您想了解更多信息,请询问。