二叉搜索树

定义

满足下列性质的二叉树(可以是空树)就是二叉搜索树:

  • 每一个节点都有一个key值,并且不同节点的key值不一样
  • root节点的左子树的所有key值都要比root节点的key值小,右子树的所有key值都要比root节点的key值大
  • root的左子树、右子树也满足二叉搜索树的性质(递归定义的二叉搜索树)

每一个节点包含一个key值,以及指向左子树和右子树的引用

带索引的二叉搜索树:在二叉搜索树的基础上,对于每一个节点都增加一个leftSize域,用来存放左子树的节点数+1,表示该节点在其子树中的排名

基本代码(Java)
BinaryNode classclass BinaryNode{
	Object key;
	BinaryNode left;
	BinaryNode right;
	
	BinaryNode(Object key,BinaryNode left,BinaryNode right){
		this.key=key;
		this.left=left;
		this.right=right;
		}
}

BinarySearchTree skeleton:

public class BinarySearchTree{
	private BinaryNode root;
	
	public BinarySearchTree(){
		root=null;
	}
	
	//下面的这些方法参数都不带递归所需要用到的BinaryNode参数
	//是因为这是提供给外部的public方法
	//实际上需要在这个public方法里面调用private方法,这个private方法里面则需要用到root来开启递归
	
	public boolean isEmpty(){
		return root==null;
	}
	
	public BinaryNode find(Object key){
		//给定一个key值,返回其所在的BinaryNode
	}
	
	public BinaryNode findMin(){
		//查找最小key
	}
	
	public BinaryNode findMax(){
		//查找最大key
	}
	
	public void insert(Object key){
		//插入一个新节点
	}
	
	public void remove(Object key){
		//删除一个节点
	}

	public void printTree(){
		//打印
	}		


部分方法的具体实现
private BinaryNode find(Object x,BinaryNode t){
		//给定一个key值,返回其所在的BinaryNode
		//递归调用自己;外部调用时,传进来的参数t为root
		if(t==null)	
			return null;
		if(x.compareTo(t.key)<0) 
			return find(x,t.left);
		else if(x.compareTo(t.key)>0) 
			return find(x,t.right);
		else 
			return t;
	}
private BinaryNode findMin(BinarNode t){
		//查找最小key,最大key也是同理
		//从t节点开始找
		//递归法,迭代也是同理
		if(t.left!=null) 
			return findMin(t.left)
		else 
			return t;
	}
private void insert(Object x,BinaryNode t){
		//插入一个新节点
		//默认插入的key在原来的二叉树里不存在,从root开始比较插
		if(t==null)  
			t=new BinaryNode(x,null,null);
		else if(x.compareTo(t.key)<0)  
			t.left=insert(x,t.left);
		else  
			t.right=insert(x,t.right);
		return t;
	}

对于删除节点而言,仍要保持二叉搜索树的性质。删除的节点P有三种情况

  • P是一个叶节点
  • P有一个非空子树
  • P有两个非空子树

如图
3种不同的删除情况
最简单的情况就是删除叶节点,直接将被删除的节点设为null即可。
对于2、3种情况,我们可以把要被删除的节点的key值用左子树的最大值/右子树的最小值替代,然后删除这个左子树的最大值/右子树的最小值(然后就是递归删除剩下的子树)

删除有两个子树的节点

private BinaryNode delete(Object x,BinaryNode t){
	//t最开始是root节点
	if(t==null)  
		return t;
	if(x.compareTo(t.key)<0)  
		t.left=delete(x,t.left);
	else if(x.compareTo(t.key)>0)  
		t.right=delete(x,t.right);
	//到这一步时,节点t就是我们要删除的值为x的节点
	//前面的部分是在二叉搜索树中找到我们需要删除的那个节点
	else if(t.left!=null && t.right!=null){
		t.key=findMin(t.right).key;
		t.right=delete(t.key,t.right);
	}
	else
		t=(t.left!=null)?t.left:t.right;
}

复杂度分析
  • 当这棵二叉搜索树的高度较高接近一颗链表时,那么时间复杂度就比较高,为O(N)
  • 对于理想情况下的二叉搜索树,复杂度为O(log2N)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值