一、概念及其介绍
二分搜索树(英语:Binary Search Tree),也称为 二叉查找树 、二叉搜索树 、有序二叉树或排序二叉树。满足以下几个条件:
- 若它的左子树不为空,左子树上所有节点的值都小于它的根节点。
- 若它的右子树不为空,右子树上所有的节点的值都大于它的根节点。
它的左、右子树也都是二分搜索树。
如下图所示:
二、适用说明
二分搜索树有着高效的插入、删除、查询操作。
平均时间的时间复杂度为 O(log n),最差情况为 O(n)。二分搜索树与堆不同,不一定是完全二叉树,底层不容易直接用数组表示故采用链表来实现二分搜索树。
三,实现代码
package datastructure.bin_tree.searchtree;
import datastructure.bin_tree.MyBinTree;
import java.util.NoSuchElementException;
public class BST {
public class TreeNode{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
private int size;
private TreeNode root;
public void add(int val){
root=add(root,val);
}
//二分搜索树的插入操作
public TreeNode add(TreeNode root,int val){
if(root==null){
TreeNode treeNode=new TreeNode(val);
size++;
return treeNode;
}
if (val>root.val){
//插入的节点值大于根本节点
//在右子树造作
root.right=add(root.right,val);
}
if (val< root.val){
root.left=add(root.left,val);
}
return root;
}
//判断元素是否存在于二叉树中
public boolean containsVal(int val){
return containsVal(root,val);
}
public boolean containsVal(TreeNode root,int val){
if (root==null){
return false;
}
if (root.val==val){
return true;
}else if (root.val<val){
return containsVal(root.right,val);
}
else
return containsVal(root.right.left, val);
}
//查找二分搜素数的最大值
public int findMax(){
if (root==null){
throw new NoSuchElementException("max is not find");
}
TreeNode node=maxNode(root);
return node.val;
}
private TreeNode maxNode(TreeNode root) {
if (root.right==null){
return root;
}
return maxNode(root.right);
}
//二分搜索树的最小值
public int findMin(){
if (root==null){
throw new NoSuchElementException("Min is not find!");
}
TreeNode node=minNode(root);
return node.val;
}
private TreeNode minNode(TreeNode root) {
if (root.left==null){
return root;
}
return minNode(root.left);
}
//删除节点
public void remove(int val){
root=remove(root,val);
}
private TreeNode remove(TreeNode root, int val) {
if (root == null) {
throw new NoSuchElementException("BST is Empty,remove fail");
}
else if (root.val < val) {
root.right = remove(root.right, val);
return root;
} else if (root.val > val) {
root.left = remove(root.left, val);
return root;
} else {
//该节点就是待删除节点
if (root.left == null) {
//左孩子为空
TreeNode right = root.right;
right = right = null;
size--;
return right;
}
if (root.right == null) {
TreeNode left = root.left;
left = root = null;
size--;
return left;
}
//此时左右子树都不为空
TreeNode successor = minNode(root.right);
// 在右子树中删除后继节点的时候就已经size --了
successor.right = removeMin(root.right);
successor.left = root.left;
// 将要删除的节点58,和BST断开关系
root.left = root.right = root = null;
return successor;
}
}
private TreeNode removeMin(TreeNode root) {
if (root.left == null) {
// 当前root就是待删除的节点
TreeNode right = root.right;
root.right = root = null;
size --;
return right;
}
// 递归去左子树中删除
root.left = removeMin(root.left);
return root;
}
public int removeMin() {
int min = findMin();
root = removeMin(root);
return min;
}
//先序遍历
private void generateBSTString(TreeNode root, int height, StringBuilder sb) {
// 边界
if (root == null) {
sb.append(generatHeightStr(height)).append("NULL\n");
return;
}
sb.append(generatHeightStr(height)).append(root.val).append("\n");
// 递归访问左子树
generateBSTString(root.left,height + 1,sb);
// 递归访问右子树
generateBSTString(root.right,height + 1,sb);
}
private String generatHeightStr(int height) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < height; i++) {
sb.append("--");
}
return sb.toString();
}
public String toString() {
StringBuilder sb = new StringBuilder();
generateBSTString(root,0,sb);
return sb.toString();
}
}