美文网首页Java数据结构与算法
Java数据结构:二叉排序树(BST)

Java数据结构:二叉排序树(BST)

作者: Patarw | 来源:发表于2020-07-18 17:21 被阅读0次

一、基本介绍

  • 二叉排序树 BST: (Binary Sort(Search) Tree), 对于二叉排序树的任何一个非叶子节点,要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大。二叉排序树是数据结构中的一类。在一般情况下,查询效率比链表结构要高。
  • 比如,下面就是一颗二叉排序树:

二、创建一颗二叉树

  • 1.以上面的图的二叉排序树为例,首先创建一个节点类
 //节点类
class Node{
 public int value; 
 public Node left; //左节点
 public Node right; //右节点
 @Override
 public String toString() {
    return "Node [value=" + value + "]";
  }
 public Node(int value) {
    super();
    this.value = value;
 }

//添加方法
public void add(Node node) {
    if(this.value > node.value) {
        if(this.left == null) {
            this.left = node;
        }else {
            this.left.add(node);
        }
    }else {
        if(this.right == null) {
            this.right = node;
        }else {
            this.right.add(node);
        }
    }
}   
}
  • 2.然后创建一个二叉排序树类

    class BinarySortTree{
     public Node root; //根节点
    
     public void addNode(Node node) {
      if(this.root == null) {
          this.root = node;
      }else {
          root.add(node);
      }       
         }        
     }
    }
    
  • 3.接下来只需要在main方法中调用BinarySortTree中的addNode方法就可以创建一颗二叉排序树了:

        public static void main(String[] args) {
          int[] arr = {7, 3, 10, 12, 5, 1, 9};
          BinarySortTree tree = new BinarySortTree();
          for(int a : arr) {
              Node node = new Node(a);
              tree.addNode(node);
          }
          tree.deleteNode(7);
     
      }
    
  • 4.而仅仅是创建还是不够的,我们还需要遍历树的方法,这里选用的是中序遍历
    节点类中添加中序遍历方法:

 //中序遍历
public void midOrder() {
    if(this.left != null) {
        this.left.midOrder();
    }
    
    System.out.println(this);
    
    if(this.right != null) {
        this.right.midOrder();
    }
}

然后再到BinarySortTree类中添加根节点的遍历:

    public void midOrder() {
        this.root.midOrder();       
  }

再到main方法中调用输出结果:
1 -》3 -》5 -》7 -》9 -》10 -》12

三、删除一个节点

删除需要三种情况来考虑,

  • 被删除的节点为叶子节点:先找到当前节点的父节点,然后把指向被删除节点的指针赋为空;
  • 被删除的节点有一个子节点:先找到当前节点的父节点,然后把指向被删除节点的指针指向被删除节点的子节点;
  • 被删除的节点有两个子节点:这个稍微有点复杂,先找到当前节点的父节点,然后把指向被删除节点的指针指向被删除节点的右子节点,再把被删除节点的左子节点通过addNode方法添加到被删除右子节点的下面。

代码:
节点类中:

    //删除方法
public void delete(int value,Node node1) {
    if(this.value > value && this.left != null) {           
        this.left.delete(value,node1);  
    }else if(this.value < value && this.right != null) {
        this.right.delete(value,node1);
    }else if(this.value == value) {
        Node node = node1;
        
        //1.当节点为叶子节点时
        if(node != null) {
        if(this.right == null && this.left == null) {
            if(node.value > value) {
                node.left = null;
            }else if(node.value <= value){
                node.right = null;
            }
        }
        //2.当节点为带单子节点时
        else if(this.right != null && this.left == null) {              
            if(node.value > value) {
                node.left = this.right;
            }else if(node.value <= value){
                node.right = this.right;
            }               
        }else if(this.left != null && this.right == null) {
            if(node.value > value) {
                node.left = this.left;
            }else if(node.value <= value){
                node.right = this.left;
            }   
        }
        //3.当节点有左右节点时
        else if(this.right != null && this.left != null){
            Node temp = null;
            if(node.value > value) {                    
                node.left = this.right;                     
                this.right.add(this.left);
            }else if(node.value <= value){                  
                node.right = this.right;
                this.right.add(this.left);
            }   
        }
        }
    }
}

//查询父节点
public Node findParent(int value) {
    if(this.value > value && this.left != null) {   
       if(this.left.value == value && this.left != null){
            return this;
        }else {
            return this.left.findParent(value);
        }
    }else if(this.value < value && this.right != null) {
          if(this.right.value == value){
                return this;
            }else {
                return this.right.findParent(value);    
            }
    }else {     
        return null;
    }

}

BinarySortTree中

        public void deleteNode(int value) {
    if(this.root.value == value) {                  
            //1.当节点为叶子节点时               
            if(this.root.right == null && this.root.left == null) {
                this.root = null;
            }
            //2.当节点为带单子节点时
            else if(this.root.right != null && this.root.left == null) {                                    
                this.root = this.root.right;            
            }else if(this.root.left != null && this.root.right == null) {
                this.root = this.root.left;
            }
            //3.当节点有左右节点时
            else if(this.root.right != null && this.root.left != null){                                                             
                    this.root.right.add(this.root.left);    
                    this.root = this.root.right;            
            }
            this.root.midOrder();
            }else {         
              root.delete(value,this.root.findParent(value));
              root.midOrder();
    }
}

相关文章

网友评论

    本文标题:Java数据结构:二叉排序树(BST)

    本文链接:https://www.haomeiwen.com/subject/qplfkktx.html