【第22期】观点:IT 行业加班,到底有没有价值?

二叉搜索树

原创 2016年08月29日 14:59:46

二叉搜索树(BST)是一种树,他的特点是节点的子树不超过两个,且大小是有顺序的,任意一点节点其左孩子小于节点值小于右孩子,他的左右子树依然满足。二叉搜索树平均深度是O(log N),所以一般不担心栈空间被耗尽。

privata static calss BinNode<AnyTape>{
	BinNode(AnyTape element){
		this(element,null,null);
	}

	BinNode(AnyTape element,BinNode<AnyTape> left,BinNode<AnyTape> right){
		this.element = element;
		this.left = left;
		this.right = right;
	}
	AnyTape element;
	BinNode<AnyTape> left;
	BinNode<AnyTape> right;
}

这是二叉搜索树数据结构的定义

二叉树主要有查找,插入删除这几个操作,下面一一描述。


二叉搜索树的查找。顾名思义如果含有该节点就返回true,否则返回false。

废话不多说看代码理解。

privata boolean search(AnyType x,BinNode<AnyType> t){
	if(t == null)
		return false;
	int result = x.compareTo(t.element);  //将x与节点值比较
	if( result < 0)		//如果X小于节点值,则递归搜索节点的左子树
		return search(x,t.left);
	else if( result > 0)	//如果X大于节点值,则递归搜索节点的右子树
		return search(x,t.right);
	else    //如果X等于节点值,则存在,返回true
		return true;
}

接下来是常用的两个函数,findMin和findMax查找最小值和最大值,最小值就是沿左侧一直向下,直到没有左子树,最大值沿右侧一直向下,没有右子树为止。

private BinNode<AnyType> findMin(BinNode<AnyType> t){
	if(t == null)
		return;
	else if(t.left == null)
		return t;
	else
		return findMin(t.left)
}
findMin采用的是递归查找,如果节点左孩子为空,返回节点,这就是最小值,如果还有继续递归。

private BinNode<AnyType> findMax(BinNode<AnyType> t){
	if(t!= null){
		while(t.right != null)
			t = t.right;
	}
		return t;
}
findMax非递归实现


二叉搜索树的插入

private BinNode<AnyType> insert(AnyType x,BinNode<AnyType> t){
	if(t == null)
		return new BinNode<>(x,null,null);
	int result = x.compareTo(t.element);
	if( result < 0)		//如果X小于节点值,则在左子树插入,递归更新
		t.left = insert(x,t.left);
	else if( result > 0)	//如果X大于节点值,则在右子树插入,递归
		t.right = insert(x,t.right);
	return t;
}


二叉搜索树的删除,相对来说remove是较为困难的。如果节点是一片叶子,直接删去就好。如果节点有一个儿子,那就父节点调整自己的链绕过该节点删除。

如果是有两个儿子的节点,用右子树最小值代替节点,因为最小值不可能有左儿子,所以第二次remove就简单多了并递归删除节点。



第一幅图是具有一个儿子的节点4删除前后情况,删除4需要他的父节点2绕过4这个节点,直接将3变成2的右孩子,完成删除。

第二幅图是具有两个儿子的节点2删除前后情况,删除2需要在右子树里找到最小值3代替2,在删除原来3位置上的3,即完成了删除。

有时候删除次数不多,通常采用懒惰删除,当节点要删掉时,仍留在树中,只是被标记为删除。

private BinNode<AnyType> remove(AnyType x,BinNode<AnyType> t){
	if(t == null)
		return t;
	int result = x.compareTo(t.element);
	if( result < 0)		//如果X小于节点值,则在左子树删除,递归更新
		t.left = remove(x,t.left);
	else if( result > 0)	//如果X大于节点值,则在右子树删除,递归
		t.right = remove(x,t.right);
	else if( t.left != null && t.right != null){	//两儿子
		t.element = findMin(t.right).element;	//找到右子树最小值
		t.right = remove(t.element,t.right)		//删除右子树最小值原来的位置
	}
	else
		t = (t.left != null)?t.left:t.right;	//如果是一个儿子或者没有,哪个儿子不为空就返回哪个儿子
	return t;
}

值得注意的是,上面的操作第一步都是先测试是否是空树,否则会产生企图通过null引用访问数据域的NullPointerException异常。


二叉树性能分析

有N个关键码的集合,构成的二叉树有Cn2n/n+1种,平均搜索长度是ASLsucc = pi*ci/n,pi是内节点的值,ci是内节点所在的层次,ASLun=pj*cj/(n+1),pj是外节点的值,cj是外节点所在的层次

最优二叉树是权值最大的结点离根节点最近

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

剑指offer 面试题63 二叉搜索树的第 k 个结点

剑指offer 面试题63 二叉搜索树的第 k 个结点题目: 给定一棵二叉搜索树,请找出其中的第 k 大的结点。 例如下面的二叉树中,按结点数值大小升序顺序,第三个结点的值是 7。 ...

【转】二叉搜索树的建立, 查找, 删除操作...

转自: http://blog.csdn.net/cnnumen/article/details/5727328   #include &lt;cstdlib&gt; #include &lt;iostream&gt; using namespace std; typedef struct _NODE { int value; struct _N

5.1.1 二叉搜索树

《STL源码剖析》之二叉搜索树
  • iFuMI
  • iFuMI
  • 2017-07-25 15:58
  • 35

二叉搜索树

二叉搜索树: 二叉树的查找很简单,先序后序中序都可以,一开始要判断是否为空。 插入要判断一下是否存在,查找时同时记录其父节点,然后直到找到空节点,插入。 删除比较复杂一点: 逐一判断: 先判断是否为空,然后查找到要删除的节点p,并记录其父节点q,如果查不到,返回false; 当p节点有两个子树时,查到其中序遍历的后继节点,即排序后的位于p节点之后的节点,记为s。查找的同时记录s的父节点r,然后将s的值复制给p,然后以s为p,r为q,将问题转换为p节点只有最多一棵子树的情况,即之后的情况。这里是

二叉搜索树常用算法(创建,遍历,插入,删除)

二叉搜索树 定义:二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值; (2)若右子树不空,则右子树上所有结点...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)