从Java中的二进制搜索树中删除节点

时间:2018-11-30 09:38:28

标签: java binary-search-tree

我正在制作一个布尔方法,该方法从二叉树中删除一个元素,      如果成功删除元素,则返回true      ,如果元素不在树中,则返回false。我遇到的问题是由于某种原因它有时没有删除该节点。我只想知道我做错了什么,请先谢谢。

这是我的代码:

public boolean delete(E e) {
    BSTDelete<E> d = new BSTDelete<E>();
    boolean deleted = d.delete(e, root);
    if (deleted)
        size -= 1;
    return deleted;
}

public class BSTDelete<E extends Comparable<E>> {

    public boolean delete(E e, TreeNode<E> root) {
        if (root == null) {
            return false;
        }
        if (e == root.element) {
            if (root.right == null && root.left == null) {
                root = null;
            } else if (root.right == null) {
                root = root.left;
            } else if (root.left == null) {
                root = root.right;
            } else

                root.element = minValue(root.left);
            delete(root.element, root.left);
            // Delete the inorder successor

        } else if (e.compareTo(root.element) < 0) {
            delete(e, root.left);
        } else {
            delete(e, root.right);
        }
        return true;
    }

    E minValue(TreeNode<E> root) {
        E minv = root.element;
        while (root.right != null) {
            minv = root.right.element;
            root = root.right;
        }
        return minv;
    }

}

这是一个不断失败的测试。第二个assertEquals说i.next()是“ Beatrice”而不是“ Carl”

    BST <String>b = new BST<String>();
    b.insert("Arthur");
    b.insert("Beatrice");
    b.insert("Carl");
    b.insert("Dagmar");

    b.delete("Beatrice");
    Iterator <String> i = b.iterator();

    assertEquals(i.next(), "Arthur");
    assertEquals(i.next(), "Carl");
    assertEquals(i.next(), "Dagmar");

    }

这是我的BSTInorderIterator类:

 public class BSTInorderIterator<E extends Comparable<E>> implements 
 java.util.Iterator<E> {
 int current = 0;
 ArrayList<E>  list  = new ArrayList<E>();
 private TreeNode<E> root;


 public BSTInorderIterator(TreeNode<E> root) {
    list = new ArrayList<E>();
    inorder(root);
    }


/** Inorder traversal from the root */
public void inorder() {
    inorder(root);
}

/** Inorder traversal from a subtree */
public void inorder(TreeNode<E> root) {
    if (root.left != null)
        inorder(root.left);
    list.add(root.element);
    if (root.right != null)
        inorder(root.right);
}

@Override
/** More elements for traversing? */
public boolean hasNext() {


    return current < list.size();
}

@Override
/** Get the current element and move to the next */
public E next() {


    return list.get(current++);
}

@Override
/** Remove the current element */
public void remove() {
    // to do: make this work correctly
}

1 个答案:

答案 0 :(得分:1)

delete中的BSTDelete方法是递归方法,但是您永远不会返回递归方法调用。因此,当您使用类似delete的方式调用false时,您的d.delete(e, root)方法将仅返回root,其中nulldelete(e, root.left)

例如,即使false可能返回root.left,因为nulltrue,您的原始方法调用也会返回delete(e, root.left),因为您不返回结果return中的。

要解决此问题,请在递归调用方法时添加public boolean delete(E e, TreeNode<E> root) { if (root == null) { return false; } if (e == root.element) { if (root.right == null && root.left == null) { root = null; } else if (root.right == null) { root = root.left; } else if (root.left == null) { root = root.right; } else root.element = minValue(root.left); return delete(root.element, root.left); // Delete the inorder successor } else if (e.compareTo(root.element) < 0) { return delete(e, root.left); } else { return delete(e, root.right); } return true; } ,这可能只是对您问题的部分解决:

from sklearn.naive_bayes import MultinomialNB
from imblearn.combine import SMOTEENN

# Observe how I imported Pipeline from IMBLEARN and not SKLEARN
from imblearn.pipeline import Pipeline
from sklearn.multiclass import OneVsRestClassifier

# This pipeline will resample the data and  
# pass the output to MultinomialNB
pipe = Pipeline([('sampl', SMOTEENN()), 
                 ('clf', MultinomialNB())])

# OVR will transform the `y` as you know and 
# then pass single label data to different copies of pipe 
# multiple times (as many labels in data)
ovr = OneVsRestClassifier(pipe)
ovr.fit(X, y)