二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
- 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
- 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
- 它的左右子树也分别为二叉搜索树
查找比较简单就不画图了~~~
二叉搜索树性能分析:
最优情况下:二叉搜索树为完全搜索树,其平均比较次数为:log2ⁿ;
最坏情况下:二叉搜索树退化为单支树,其平均比较次数为:n/2
public class BSTree {
public static class Node{
public int val;
public Node left;
public Node right;
public Node(int val) {
this.val = val;
}
}
public Node root=null;
//插入数据==========================================================================
public boolean insert(int val){ //给二叉搜索树里插入一个值
Node node=new Node(val);
if(root==null){
root=node;
return true;
}
Node cur=root;
Node parent=null;//记录cur的前驱
while(cur!=null){
if(cur.val==val){
return false;
}else if(val<cur.val){//将要插入的值和cur比较,当cur不为空时,一直往下遍历
parent=cur;
cur=cur.left;
}else{
parent=cur;
cur=cur.right;
}
}
//cur为空了,位置找到进行插入,两种情况,比较看是插在左边还是右边
if(parent.val>val){
parent.left=node;
}else{
parent.right=node;
}
return true;
}
public void preOrder(Node root){//前序遍历和下面的中序遍历是为了看看构造的树是否是二叉搜索树
if(root==null) return;
System.out.print(root.val+" ");
preOrder(root.left);
preOrder(root.right);
}
public void inOrder(Node root){
if(root==null) return;
inOrder(root.left);
System.out.print(root.val+" ");
inOrder(root.right);
}
//查找数据==============================================================================
public Node search(int val){
Node cur=root;
while(cur!=null){
if(cur.val==val){
return cur;
}else if(cur.val<val){
cur=cur.right;
}else{
cur=cur.left;
}
}
return null;
}
//删除数据============================================================================
public boolean remove(int key){
//先找到数据是否存在,存在找到位置才能删除
Node cur=root;
Node parent=null;//记录cur的前驱
while(cur!=null){
if(cur.val==key){//相同的就删除
removeNode(parent,cur);//删除节点的方法
return true;
}else if(key<cur.val){//不同就继续往下找,直到找到相同的然后使用removeNode方法
parent=cur;
cur=cur.left;
}else{
parent=cur;
cur=cur.right;
}
}
return false;
}
public void removeNode(Node parent,Node cur){
//以下的几种情况自己画图了解!!!
if(cur.left==null){
if(cur==root){
root=cur.right;
}else if(cur==parent.left){
parent.left=cur.right;
}else{
parent.right=cur.right;
}
}else if(cur.right==null){
if(cur==root){
root=cur.left;
}else if(cur==parent.left){
parent.left=cur.left;
}else{
parent.right=cur.left;
}
}else{//cur的左右都不为空的情况,这里写的是往右边找最小值的情况,不懂的地方自己画图,图画出来就一切真相大明了。
Node targetParent=cur;
Node target=cur.right;//往右找最小值
while(target.left!=null){
targetParent = target;
target=target.left;
}
cur.val=target.val;
if(target==targetParent.left) {
targetParent.left = target.right;
}else{
targetParent.right = target.right;//这一步对应上图中的49,即万一向右找最小值,但是49只有右边没有左边的情况
}
}
}
public static void main(String[] args) {
BSTree bsTree=new BSTree();
int[] array={12,8,30,2,10,20,49,16,35,50,44};
for(int i:array){//构造一棵二叉树,将数组中所有的数据插进去
bsTree.insert(i);//它每往进插入一个数据,都是按照二叉搜索树的规则来的,因为insert函数就是这么写的
}
//前序和中序遍历能够确定一棵二叉树,这样遍历一下就可以判断插入的是否是一棵二叉搜索树
bsTree.preOrder(bsTree.root);
System.out.println();
bsTree.inOrder(bsTree.root);
System.out.println();
System.out.println("是否插入成功:");
System.out.println(bsTree.insert(9));//true
bsTree.preOrder(bsTree.root);
System.out.println();
bsTree.inOrder(bsTree.root);
System.out.println();
System.out.println("是否找到数据:");
System.out.println(bsTree.search(20).val);//20
//System.out.println(bsTree.search(200).val);//空指针异常:Exception in thread "main" java.lang.NullPointerException
System.out.println("是否成功移除数据:");
System.out.println(bsTree.remove(49));
bsTree.preOrder(bsTree.root);
System.out.println();
bsTree.inOrder(bsTree.root);
System.out.println();
}
}
执行结果: