本人是算法小白,java写得比较多,因此不说算法具体实现和列代码,也没那个实力,因此本文的出发点是,对算法不很是感冒的小白作个简易了解。java
参考:算法导论算法
便于查找特定数据,按关键字大小构造的一棵二叉树,红黑树和B-Tree都是二叉搜索树的变形,因此二叉搜索树很关键又很容易掌握。多说无益,直接给demoblog
这是用一个手机软件画的(看水印就知道了),很好用,在这里给它打个小广告。排序
一个结点x,x.key表明x的关键字,x.left表明x的左孩子,x.right表明x的右孩子,x.p表明x的双亲(parent,或者叫父亲) 递归
这是一棵二叉搜索树,它的特色就是对于任意一个结点,其左子树中最大关键字都不超过x.key,其右子树中最小关键字都不小于x.key。这样结构很容易联想到二分法,二分法在一个有序序列找一个数效率是挺可观的。效率
在demo中,咱们要找20,就从根结点40开始,40>20,因此咱们去40的左孩子9,9<20,因此去9的右孩子,20==20,找到了。固然若是找不到就返回NULL或者NIL(算法书里面用来讲明该结点是空的一个特殊结点),因而乎,很容易想象到二叉搜索树的查找代码就是一个简单的递归。软件
demo中若是细心就会发现这棵书的右边很臃肿,二叉搜索树的缺点即是在这里,这棵树很是不平衡,或者说数据很是极端,偏向于某一边,那么这个树的查找效率就跟遍历一个序列没什么差异,因此红黑树的目的就是让二叉搜索树近似于平衡。二叉树
由于二叉搜索树的特色,若是中序遍历这棵树,输出的序列就是全部关键字的正向排序。能够试下中序遍历demo,输出就是3,6,9,13,20,40,50,65,73,90搜索
插入比较简单,跟查找相似,一直往下,比新结点z小就往左,比z大就往右,知道遇到NULL或者NIL,就挂在那个叶子结点上。插入一直是在后面树的底插,因此二叉搜索树的根结点就是第一个插入的结点,并且不能保证这棵树是否是平衡遍历
删除分三种状况:
后继:一个结点x的后继,就是关键字大于x.key的结点中最小的那个,注意这里有两种状况,若是x是有右子树,那就是x的右子树中最小那个,也就是x的右子树的最左那个结点;若是x是没有右子树,那就须要往上找,从x的父结点开始,一直往左上走(对的是左上方向),一直没有路了,那终点的父节点就是x的后继了。对于第二种状况我给个图:
回到刚刚删除的第三种状况,删除结点z有两个孩子,咱们须要找到z的后继y(必定会在z的右子树( ̄▽ ̄) ,额好像上面白讲了),用z的后继y代替z,z的右子树成为y的新的右子树,z的左子树称为y的新的左子树。这里直接上算法导论的图