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

时间:2013-07-17 16:18:58

标签: java binary-search-tree

我有BST的测试代码。 BST已创建,但节点删除无法正常工作。如果下面的删除代码是正确的,或者删除方法中的任何修改都是非常有帮助的任何帮助。

public class BinarySearchTree {
  public BinarySearchTree() {
    super();
  }

  private class BinarySearchTreeNode{
    private int data;
    private BinarySearchTreeNode left;
    private BinarySearchTreeNode right;

    public BinarySearchTreeNode(){
    }

    public BinarySearchTreeNode(int data){
      this.data = data;
    }

    public void setData(int data) {
      this.data = data;
    }

    public int getData() {
      return data;
    }

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

    public BinarySearchTree.BinarySearchTreeNode getLeft() {
      return left;
    }

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

    public BinarySearchTree.BinarySearchTreeNode getRight() {
      return right;
    }
  }

  public BinarySearchTreeNode insertRec(BinarySearchTreeNode root,int data){
    if(root == null){
      root = new BinarySearchTreeNode(); 
      root.setData(data);
      root.setLeft(null);
      root.setRight(null);
    }else{
        if(data < root.getData())
          root.setLeft(insertRec(root.getLeft(), data));
        else if(data > root.getData())
          root.setRight(insertRec(root.getRight(), data));
    }

    return root;
  }

  public void insertNonRec(BinarySearchTreeNode root,int data){
    if(root == null){
      root = new BinarySearchTreeNode(data); 
      root.setLeft(null);
      root.setRight(null);
    }else{
      if(data < root.getData()){
        if(root.getLeft() != null){
          insertNonRec(root.getLeft(),data);
        }else{
          root.setLeft(new BinarySearchTreeNode(data));
        }
      }else if(data > root.getData()){
        if(root.getRight() != null){
          insertNonRec(root.getRight(), data);
        }else{
          root.setRight(new BinarySearchTreeNode(data));
        }
      }
    }
  }

  public void delete(BinarySearchTreeNode root,int data){
    BinarySearchTreeNode temp;
    if(root == null){
      System.out.println("No elemets in BST.");
    }else if(data < root.getData()){
      delete(root.getLeft(),data);
    }else if(data > root.getData()){
      delete(root.getRight(),data);
    }else{
      if((root.getLeft() != null) && (root.getRight() != null)){
        // Replace with largest in left subtree 
        temp = findMax(root.getLeft());
        root.setData(temp.getData());
        delete(root.getLeft(),temp.getData());
      }else if(root.getLeft() != null || root.getRight() != null){
        // One child
        if(root.getLeft() == null){
          //root = root.getRight();
          root.setData(root.getRight().getData());
          root.setRight(null);
        }else if(root.getRight() == null){
          //root = root.getLeft();
          root.setData(root.getLeft().getData());
          root.setLeft(null);
        }
      }else{
        root = null;
      }
    }
  }

  public BinarySearchTreeNode findMax(BinarySearchTreeNode root){
    if(root == null)
      return null;

    while(root.getRight() != null)
      root = root.getLeft();

    return root;
  }

  public BinarySearchTreeNode findMin(BinarySearchTreeNode root){
    if(root == null)
      return null;

    while(root.getLeft() != null)
      root = root.getLeft();

    return root;
  }

  public void inOrderRec(BinarySearchTreeNode root){
    if(root != null){
      inOrderRec(root.getLeft());
      System.out.print(root.getData() + " ");
      inOrderRec(root.getRight());
    }
  }

  public static void main(String args[]){
    BinarySearchTree tree = new BinarySearchTree();
    BinarySearchTreeNode root = tree.insertRec(null, 10);

    tree.insertNonRec(root, 5);
    tree.insertNonRec(root, 20);
    tree.insertNonRec(root, 4);
    tree.insertNonRec(root, 8);
    tree.insertNonRec(root, 12);
    tree.insertNonRec(root, 30);
    tree.insertNonRec(root, 11);
    tree.insertNonRec(root, 13);

    System.out.println("InOrder Traversal :");
    tree.inOrderRec(root);

    tree.delete(root, 20);

    System.out.println("");
    System.out.println("InOrder Traversal :");
    tree.inOrderRec(root);
  }
}

输出:

InOrder Traversal :
4 5 8 10 11 12 13 20 30 

InOrder Traversal :
4 5 8 10 11 12 13 11 30

1 个答案:

答案 0 :(得分:1)

root = null;没有按照您的想法行事。它仅更改局部变量的值。它不会改变树。简短的比喻:

  

想想一个学生的课堂。学生是树中的节点。他们互相指向,定义了树中的父母身份。现在,如果另一个学生(比如John,即函数的参数)出现并指向“树”中的一个学生(说Sarah),说root = null;将等同于约翰现在无处指向,它不会改变莎拉,也不会改变其他学生所指的是什么。

当然,我的比喻中有一些漏洞,但我希望你能得到基本的想法。

您需要执行node.setLeft(null);node.setRight(null);之类的操作来实际更改树。

这将需要进行相当多的更改,我将留给您解决(thisthis可能会有所帮助),但请注意,为此,您显然会有检查左右儿童,而不是(只)根。

我还建议您查看Red-black trees(或类似),因为它们提供了更有效的删除节点的方法,同时也保持了树的平衡。