Java 从二叉搜索树中删除元素
我正在做一个作业,实现自己的二叉搜索树。问题是,我们有自己的节点实现,它的父节点不能直接访问 我一直在寻找答案,但我不想完全照搬解决方案,尽管如此,我似乎仍然没有找到正确的答案。我错过了一些未删除元素的情况 你能帮帮我吗?我做错了什么 这是删除方法:Java 从二叉搜索树中删除元素,java,binary-search-tree,Java,Binary Search Tree,我正在做一个作业,实现自己的二叉搜索树。问题是,我们有自己的节点实现,它的父节点不能直接访问 我一直在寻找答案,但我不想完全照搬解决方案,尽管如此,我似乎仍然没有找到正确的答案。我错过了一些未删除元素的情况 你能帮帮我吗?我做错了什么 这是删除方法: void remove(E elem) { if(elem != null){ if (root != null && contains(elem)) { removeFromSu
void remove(E elem) {
if(elem != null){
if (root != null && contains(elem)) {
removeFromSubtree(elem, root, null);
}
}
}
void removeFromSubtree(E elem, Node<E> current, Node<E> parent) {
if(elem.less(current.contents)){
if(current.left == null) return ;
removeFromSubtree(elem, current.left, current);
} else if(elem.greater(current.contents)){
if(current.right == null)return;
removeFromSubtree(elem, current.right, current);
} else {
if(current.left != null && current.right != null){
//both children
if(parent == null){
Node<E> n = new Node<>(null, null);
n.left = root;
removeFromSubtree(root.contents, n, null);
root = n.left;
root.setParent(null);
}
E min = subtreeMin(current.right);
current.contents = min;
removeFromSubtree(min, current.right, current);
} else if(current.left != null){
//left child
if (parent == null) {
root = current.left;
current.left.setParent(null);
return ;
}
setParentChild(current, parent, current.left);
} else if(current.right != null){
//right child
if (parent == null) {
root = current.right;
current.right.setParent(null);
return ;
}
setParentChild(current, parent, current.right);
} else {
if (parent == null) {
root = null;
return ;
}
setParentChild(current, parent, null);
}
}
}
void删除(E元素){
if(elem!=null){
如果(root!=null&&contains(elem)){
removeFromSubtree(元素、根、空);
}
}
}
void removeFromSubtree(元素、节点当前、节点父节点){
if(元素较少(当前内容)){
if(current.left==null)返回;
removeFromSubtree(elem,current.left,current);
}else if(元素更大(当前内容)){
if(current.right==null)返回;
removeFromSubtree(elem,current.right,current);
}否则{
if(current.left!=null&¤t.right!=null){
//两个孩子
如果(父项==null){
节点n=新节点(null,null);
n、 左=根;
removeFromSubtree(root.contents,n,null);
根=n.左;
root.setParent(null);
}
E最小值=次行程最小值(当前右侧);
current.contents=min;
removeFromSubtree(最小,当前。右侧,当前);
}else if(current.left!=null){
//左撇子
如果(父项==null){
root=current.left;
current.left.setParent(空);
返回;
}
setParentChild(当前,父,当前.左);
}else if(current.right!=null){
//对的孩子
如果(父项==null){
root=current.right;
current.right.setParent(空);
返回;
}
setParentChild(当前,父,当前.右);
}否则{
如果(父项==null){
root=null;
返回;
}
setParentChild(当前、父级、空);
}
}
}
节点使用通用接口
class Node<E extends DSAComparable<E>>
类节点
只有比较的方法。看起来像这样
interface DSAComparable<E extends DSAComparable<E>> {
boolean less(E other);
boolean greater(E other);
boolean equal(E other);
}
接口DSA可比较{
布尔少(E其他);
布尔更大(E其他);
布尔相等(E其他);
}
我在remove中使用了另一种方法来设置节点的父节点的子节点,这取决于它的左子节点还是右子节点
void setParentChild(Node<E> node, Node<E> parent,Node<E> value){
if(parent!= null){
if (parent.left == node) {
parent.left = value;
} else {
parent.right = value;
}
if(value!= null) value.setParent(parent);
}
}
void setParentChild(节点节点、节点父节点、节点值){
如果(父项!=null){
if(parent.left==节点){
parent.left=值;
}否则{
parent.right=值;
}
if(value!=null)value.setParent(parent);
}
}
方法subtreeMin(Node Node)查找子树中最小的值(最左边的)理解代码并不容易,因为它仍然缺乏细节 我会提到这样一个二进制搜索树的实现,你可以在网上找到
例如,请参见。您到底需要什么?您报告的大多数代码调用的方法不是来自JDK。如果没有任何额外的细节,几乎不可能在某些情况下,当元素应该被移除时却没有被移除。我不知道哪些条件我没有包括在内。我介绍了childen null、任一child null和no child null,以及删除root时的情况。我还是不明白。所以我的问题是,是否有我没有包含的条件?您必须提供其他方法的实现。例如,您如何处理
elem.less()
?我编辑了答案,希望它会有所帮助。如果(root!=null&&contains(elem))中包含else
,可能会有所帮助。然后,如果有一个值始终没有被删除,那么您可以在该值中打断,以检查事物的状态。我的直觉是,contains没有返回你一直期待的结果。