Binary search tree (BST) --- java implementation

1. Definition

A binary search tree (BST) is a binary tree whose value of each node is larger than any node of the left child and smaller than any node of the right child.

Second, the data structure

public class BinarySearchTree<T extends Comparable<? super T>>  {

    private TreeNode<T> root;

    public BinarySearchTree(TreeNode<T> root) {
        this.root = root;
    }
}

class TreeNode<T>{
    T data;
    TreeNode lchild;
    TreeNode rchild;

    public TreeNode(T data) {
        this(data,null,null);
    }

    public TreeNode(T data, TreeNode lchild, TreeNode rchild) {
        this.data = data;
        this.lchild = lchild;
        this.rchild = rchild;
    }


}

Three, contains method

Returns true if data X exists in the tree, otherwise returns false.
We only need to start traversing from the root node, if the current node is less than X, then recurse to the left, otherwise recursive to the right until we find X or reach the end of the tree.

 public boolean contains(T x){
        return  contains(x,root);
    }
    private boolean contains(T x, TreeNode<T> root) {
        if (root==null){
            return false;
        }
        int result=x.compareTo(root.data);
        if (result<0){
            return contains(x,root.lchild);
        }else if (result>0){
            return contains(x,root.rchild);
        }else {
            return true;
        }

    }

Fourth, find the minimum and maximum

A binary search tree, the minimum value must be found recursively according to the left subtree until the bottom of the tree
1. If the root node is empty, it returns empty
2. If the left subtree is empty, it returns the root node
3. Otherwise The left child starts and continues to recur from 1.

 public TreeNode<T> findMax(TreeNode<T> root){
        if (root==null){
            return null;
        }
        while (root.rchild!=null){
            root=root.rchild;
        }
        return root;
    }

Finding the maximum value is the opposite, looping from the root node to the right subtree.

public TreeNode<T> findMax(TreeNode<T> root){
        if (root==null){
            return null;
        }
        while (root.rchild!=null){
            root=root.rchild;
        }
        return root;
    }

Five, insert a node

You can also use the recursive way of contains.
If X is found, the node already exists and does nothing; otherwise, it is inserted into the last node on the traversal path.

public TreeNode<T> insert(T x){
        if (x==null){
            throw new IllegalArgumentException("参数为空");
        }
        return insert(x,root);
    }
    private TreeNode<T> insert(T x,TreeNode<T> t){
    	//当前节点为空,构建一个新的节点插入x
        if (t==null){
            return new TreeNode<>(x);
        }
        int result=x.compareTo(t.data);
        if (result<0){
        	//向左递归
            t.lchild=insert(x,t.lchild);
        }else if (result>0){
     	   //向右递归
            t.rchild=insert(x,t.rchild);
        }
        return t;
    }

Six, delete a node

The deletion of node X can be roughly divided into three cases:

  1. If X is a leaf node, delete it directly
  2. If X has a child, put that child at the current node position
  3. If X has two children, find the smallest node Y of the right child and put it at the position of the node X to be deleted, so that the left children of X are still smaller than it. Now only need to delete the Y of the right child in the same way That's it.
 public void remove(T x){
        if (x==null){
            return;
        }
        remove(x,root);
    }

    /**
     * 删除一个节点
     * 1.如果是叶子节点,则直接删除
     * 2.如果有一个孩子,让当前节点等于那个孩子
     * 3.如果有两个孩子,让当前节点的值等于右孩子中最小的一个节点的值,然后再同样的方法删除右孩子最小值的节点
     * @param x
     * @param root
     * @return
     */
    private TreeNode<T> remove(T x,TreeNode<T>root){
        if (root==null){
            return null;
        }

        int result=x.compareTo(root.data);
        if (result<0){
            root.lchild=remove(x,root.lchild);
        }else if (result>0){
            root.rchild=remove(x,root.rchild);
        }else if (root.lchild!=null&&root.rchild!=null){ //找到待删除节点,且有两个孩子
        	//让当前节点值等于右孩子最小的节点值
            root.data= (T) findMin(root.rchild).data;
            //在右孩子中删除上一步找到的最小的值
            root.rchild=remove(root.data,root.rchild);
        }else {
            root=root.lchild==null?root.rchild:null;
        }
        return root;
    }

Finding the height of a node is simple:

 public int height(TreeNode<T> root){
        if (root==null){
            return -1;
        }
        return 1+Math.max(height(root.lchild),height(root.rchild));
    }

Summary:
The running time of a binary search tree depends on the shape of the tree, which in turn depends on the order in which the data is inserted. Therefore, the best case is a complete binary tree; but in the worst case, there are N nodes in the search path, that is, the left and right nodes are lined up under one path.

The worst-case order of magnitude increase in run time:
lookup: N
insert: N
average case:
find hit: 1.39lgN
insert: 1.39lgN
supports orderly related operations

Published 75 original articles · won praise 13 · views 8369

Guess you like

Origin blog.csdn.net/weixin_43696529/article/details/104697184