二叉查找树(二叉排序树)BST解析

本文详细介绍了二叉排序树的基本概念、查找、插入与删除操作的实现原理及代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二叉排序树又名二叉查找树,不同于普通的二叉树,该形式可以使二叉树有序,使其左孩子一定小于该节点值,右孩子一定大于该节点值,于是其中序遍历便是一个递增的数列。同时故其查找效率为O(lgN)即二叉树的高度。

下面首先介绍下BST树的查找算法。
BST树查找很简单,首先根节点,如果比该节点值大从其右孩子中查找,如果比其小则从其左孩子中查找。直到找到或者该节点为空为止。
下面是查找的代码实现
public boolean findNode(int aim) {
        /*二叉排序树的查找  时间复杂度为O(lgn)*/
        TreeNode current = root;
        while (current != null && current.value != aim) {
            if (current.value > aim)
                current = current.left;
            else if (current.value < aim)
                current = current.right;
            else if(current.value==aim)
                return true;
        }
        return false;
}
下面介绍插入节点。插入节点其实首先也得进行查找,查找该插入的节点放在什么位置。
首先如果该插入节点大于该节点root,则对其右孩子进行查找,如果小于root则对其左孩子进行查找。直到找到某节点其左孩子或者右孩子为空,则插入。
 public void insert(int aim){
    	TreeNode node=new TreeNode();//新建插入的节点
    	node.value=aim;
    	TreeNode current=root;
    	TreeNode father=null;
    	boolean isLeftNode=false;
    	if(current==null)//根节点为空
    		current=node;
    	else{
    		while(current!=null){
    			father=current;
    			if (current.value > aim)
    			{	isLeftNode=true;
    				current = current.left;
    			}else{
    				current = current.right;
    			    isLeftNode=false;
    			}
    		}
    		if(isLeftNode)
    			father.left=node;
    		else father.right=node;
    	}
    }
其实有了插入方法,也就可以顺手写出创建BST的方法,直接上代码
 public TreeNode build(int[] aim){
    	TreeNode root=new TreeNode();
    	root.value=aim[0];
    	this.root=root;
    	for(int i=1;i<aim.length;i++){
    		insert(aim[i]);
    	}
    	return root;
    }
下面介绍BST最难的删除节点。
删除的节点分三种情况
1、该节点为叶子节点。这种情况直接删除即可
2、该节点拥有左孩子或者拥有右孩子(只拥有一个)。这种情况删除该节点,并让father节点与其为空的左孩子或者右孩子连接即可
3、该节点左孩子与右孩子都不为空。这时候要考虑用什么节点替代该删除的节点,是左孩子还是右孩子。
本文采用了利用该节点右孩子的最小值来替代该节点。当然也可以用其左孩子的最大值来替代。



 public void delete(int aim){
        TreeNode current=root;
        TreeNode father=null;
        boolean isLeftNode=false;
        while(current!=null&¤t.value!=aim){
            father=current;
            if (current.value > aim)
            {    isLeftNode=true;
                current = current.left;
            }else{
                current = current.right;
                isLeftNode=false;
            }
        }
        if(current.left==null&¤t.right==null){//情况1
            if(current==root)
                root=null;
            else if(isLeftNode)
                father.left=null;
            else father.right=null;
        }else if(current.left!=null&¤t.right==null){//情况2
            if(current==root)
                root=current.left;
            else if(isLeftNode)
                father.left=current.left;
            else father.right=current.left;
        }else if(current.left==null&¤t.right!=null){
            if(current==root)
                root=current.right;
            else if(isLeftNode)
                father.left=current.right;
            else father.right=current.right;
        }else if(current.left!=null&¤t.right!=null){//情况3*
            TreeNode next=getNextNode(current);//获取后继节点(右孩子上的最小节点)
            if(current==root)
                root=next;
            else if(isLeftNode)
                father.left=next;
            else father.right=next;
            next.left=current.left;
        }
    }
    public TreeNode getNextNode(TreeNode root){//获取其右孩子的最小节点
        TreeNode del=root;
        TreeNode current=root.right;
        TreeNode nextfather=null;
        TreeNode next=null;
        while(current!=null){
            nextfather=next;
            next=current;
            current=current.left;
        }
        if(next!=del.right){//该最小节点一定没有左孩子但是可能有右孩子。如果有要将其右孩子变为被删除节点右孩子的左孩子,见下图示。
            nextfather.left=next.right;
            next.right=del.right;
        }
        return next;
    }

对了,BST树的结构和普通二叉树一样,代码如下
class TreeNode {
	TreeNode left;
	TreeNode right;
	int value;
	public TreeNode() {
		left = null;
		right = null;
		value = 0;
	}
}
下面用中序遍历进行输入,中序代码为:
 public void printPre(TreeNode node){//中序遍历
    	if(node!=null){
    		printPre(node.left);
    		System.out.print(node.value+" ");
    		printPre(node.right);
    	}
    	
    }
全部都有了,我们可以进行测试下的啦。看看输出。
public static void main(String[] args) {
		// TODO Auto-generated method stub
        int[] aim={3,5,1,2,7,4,6,12};
        BinarySearchTree bTree=new BinarySearchTree();
        TreeNode root=bTree.build(aim);
        System.out.println("构建BST树的中序为:");
        bTree.printPre(root);
        bTree.insert(0);
        System.out.print("\n插入节点0后中序为:");
        bTree.printPre(root);
        System.out.print("\n查找节点值为8:");
        System.out.println(bTree.findNode(8)?"8找到":"8未找到");
        bTree.insert(8);//插入8,9,10
        bTree.insert(9);
        bTree.insert(10);
        bTree.printPre(root);//插入8,9,10后的中序
        bTree.delete(7);
        System.out.println("\ndel节点7后中序为:");
        bTree.printPre(root);
        System.out.println();
} 
输出的结果为:

the end!不吝赐教


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值