Bst树delete()方法不起作用

时间:2015-07-22 18:09:04

标签: java binary-search-tree

我目前正在实现二进制搜索树,我想知道为什么我的delete()方法不起作用... 我的findMin()方法确实有效,到目前为止我已经测试过了。 我输入一个密钥,它在三个中不存在,我得到了正确的异常,但每当我输入一个存在的密钥时,它就不会从三个中移除该节点... 所以这是我目前的代码:

import java.util.NoSuchElementException;

public class Bst {

Node root;
Node head;
Node tail;


public Bst(){
    root = null;
}

public void insert (Node root, int key){
    Node newNode=new Node(key);

    if(root==null){
        root=newNode;
    }

    if(key<=root.getKey()){
        if (root.getLeft()!=null){
            insert(root.getLeft(), key);
        }
        else{
            root.setLeft(newNode);
        }
    }

    if (key>=root.getKey()){
        if (root.getRight()!=null){
            insert(root.getRight(),key);
        }

        else{
            root.setRight(newNode);
        }

    }


    }

public void printTree(Node root){
    if (root==null) return;
    printTree(root.getLeft());
    System.out.print(root.getKey() + " ");
    printTree(root.getRight());
}

public Node treeToCDLL(Node root){
    if (root == null){
        return null;
    }

    Node leftTree=treeToCDLL(root.getLeft());
    Node rightTree=treeToCDLL(root.getRight());


    if (leftTree == null){
        head=root;
    }

    else {
        head=leftTree;
        leftTree.getLeft().setRight(root);
        root.setLeft(leftTree.getLeft());
    }

    if (rightTree==null){
        head.setLeft(root);
        root.setRight(head);
        tail=root;
    }

    else{
        tail=rightTree.getLeft();
        head.setLeft(tail);
        tail.setRight(head);
        root.setRight(rightTree);
        rightTree.setLeft(root);
    }

    return head;
}

public boolean find(Node root, int key){
    Node current=root;

    while(current!=null){

        if(current.getKey()==key){
            return true;
        }
        else if(current.getKey()>key){
            current=current.getLeft();
        }

        else
            current=current.getRight();
        }
    return false;
}

public void printList(Node head){
    Node current = head;

    while(current!=null){
        System.out.print(current.getKey() + " ");
        current=current.getRight();
        if(current==head) break;
    }
}

public Node findMin(Node root){
    Node current=root;
    if(root==null) return null;
    else{
    if(current.getLeft()!=null){
        return findMin(current.getLeft());
    }
    }
    return current;

}

public void delete(Node root, int key){
    Node current=root;

    if(root==null){
        throw new NoSuchElementException("baum ist leer");
    }

    else{
        if(current.getKey()>key){
            delete(current.getLeft(), key);
        }

        else if(current.getKey()<key){
            delete(current.getRight(),key);
        }

        else{
            if(current.getLeft()==null && root.getRight()==null){
                current=null;
            }

            else if(current.getLeft()==null){
                Node tmp=current;
                current=current.getRight();
                tmp=null;
            }

            else if(current.getRight()==null){
                Node tmp=current;
                current=current.getLeft();
                tmp=null;
            }

            else {
                Node min=findMin(current.getRight());
                Node tmp=current;
                current=min;
                tmp=null;

            }
        }
    }
}
public static void main (String[]args){

    Bst bst=new Bst();

    Node root=new Node(4);
    bst.insert(root, 2);
    bst.insert(root, 10);
    bst.insert(root, 3);
    bst.insert(root, 5);
    bst.insert(root, 6);
    bst.insert(root, 0);

    bst.delete(root, 2);

    System.out.print("in-order traversal: ");
    bst.printTree(root);
    System.out.println();
    System.out.print("Der gesuchte Knoten : " + bst.find(root,7));
    System.out.println();
    System.out.print("der kleinste Knoten : " + bst.findMin(root));
    System.out.println();



    System.out.print("circular doubly linked list: ");
    Node head= bst.treeToCDLL(root);
    bst.printList(head);







}

}

节点类:

public class Node {

    private Node left;
    private Node right;
    private int key;

    public Node(int key){
        this.key=key;
        left = null;
        right = null;
    }

    public void setLeft(Node left){
        this.left=left;
    }

    public Node getLeft(){
        return left;
    }

    public void setRight(Node right){
        this.right=right;
    }

    public Node getRight(){
        return right;
    }

    public int getKey(){
        return key;
    }

}

如果有人能帮助我,我会很高兴... 我试着整天找到一个解决方案,但似乎我不会在我自己的

上找到它

2 个答案:

答案 0 :(得分:0)

这里,通过执行此current = min,您不是在树中更改节点,而只是替换本地指针(当前)。 要么通过setter重写此节点的值,要么在节点的父节点上获取更新getLeft。

 else {
     Node min=findMin(current.getRight());
     Node tmp=current;
     current=min;
     tmp=null;
 }

答案 1 :(得分:0)

delete()方法的最后一部分中,您只是简单地指定null值并不意味着引用将指向null值。

例如,当匹配的节点是叶节点时,您只需将null值分配给current变量。您应该将null值分配给left父母的right / current。假设parentcurrent节点的父节点。

 if(current.getLeft()==null && root.getRight()==null){
            if(current == parent.getLeft()) {
                 parent.left=null;
            } else {
                 parent.right == null;
            }
  }

这些与其他后续else块存在同样的问题。

        else if(current.getLeft()==null){
            if(current == parent.left) {
                 parent.left= current.getRight();
            } else {
                 parent.right = current.getRight();
            }
        }

        else if(current.getRight()==null){
            if(current == parent.left) {
                 parent.left= current.getLeft();
            } else {
                 parent.right = current.getLeft();
            }
        }

您需要在遍历树时跟踪父节点。