平衡二叉树各种算法详解一:红黑树
来源:互联网 发布:武汉java培训班 编辑:程序博客网 时间:2024/05/22 06:48
平衡二叉树(Balanced Binary Tree)具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用算法有红黑树、AVL、Treap、伸展树、SBT等。最小二叉平衡树的节点的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。平衡二叉树的时间复杂度为o(h),h为树高,保持树矮胖的形态有利于提高算法的效率。
平衡二叉树中常见操作有插入,删除,旋转等。
旋转是维持平衡二叉树必要的操作,包括左旋和右旋,二者成镜像对称。
左旋算法如下(T.ROOT表示树根,NIL表示空结点)
def Left-Rotate(x): y=x.right if(y.left!=NIL): y.left.parent=x x.right=y.left if(x.parent==NIL): T.ROOT=y else if(x.parent.left==x): x.parent.left=y else x.parent.right=y y.parent=x.parent x.parent=y y.left=x
右旋与之类似,故不再贴出代码。
插入算法如下:
def Tree-Insert(T,z): y=NIL //use y as the parent of x x=T.ROOT while(x!=NIL): y=x if(z.value<x.value): x=x.left else x=x.right z.parent=y if(y==NIL): //tree is empty T.ROOT=z else if(z.value<y.value): y.left=z else y.right=z
删除算法需要考虑三种情况:
1. z没有子结点,直接删除,修改z的父结点,再用NIL替代z即可
2. z只有一个子结点,将其提升到z的位置,修改z的父结点,再用z的子结点代替z
3. z有两个子结点,这时稍麻烦一点,需要寻找z的后继,即z的右子树中最小的一个结点,还要考虑后继正好为z的右孩子的情况
首先定义一个子树的移植算法:
def Transplant(T,u,v): //用以v为根的子树替代以U为根的子树 if(u.parent==NIL) T.ROOT=v else if(u==u.parent.left) u.parent.left=v else u.parent.right=v if(v!=NIL) v.parent=u.parent
再定义一个寻找后继的方法:
def Tree-min(z): if(z.left!=NIL) z=z.left return z
利用现成的移植算法进行删除:
def Tree-delete(T,z) if(z.left==NIL) Transplant(T,z,z.right) else if(z.right==NIL) Transplant(T,z,z.left) else y=Tree-min(z.right) //y is the successor of z if(y.parent!=z) Transplant(T,y,y.right) y.right=z.right y.right.parent=y Transplant(T,z,y) z.left.parent=y y.left=z.left
这就是平衡二叉树中常见的旋转,插入,删除算法。由于插入,删除有可能改变树的平衡性,所以需调用旋转方法以保持树的平衡性。
下面举例详解各种平衡二叉树。
红黑树:
红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。红黑树在很多地方都有应用。在C++ STL中,很多部分(包括set, multiset, map, multimap)应用了红黑树的变体(SGI STL中的红黑树有一些变化,这些修改提供了更好的性能,以及对set操作的支持)。
红黑树的插入:
def RB-Insert(T,z): y=T.nil //use y as the parent of x x=T.ROOT while(x!=T.nil): y=x if(z.value<x.value): x=x.left else x=x.right z.parent=y if(y==T.nil): //tree is empty T.ROOT=z else if(z.value<y.value): y.left=z else y.right=z z.left=T.nil z.right=T.nil z.color=RED //z is red RB-Insert-fixup(T,z) //make the tree follow red-black rule
插入后修复树的颜色:def RB-Insert-fixup(T,z) while(z.parent.color==RED) if(z.parent==z.parent.parent.left) y=z.parent.parent.right //y is the uncle node of z if(y.color==RED) //case 1 z.p.color=BLACK y.color=BLACK z.parent.parent.color=RED z=z.parent.parent else if(z==z.parent.right) //case 2 z=z.parent Left-Rotate(T,z) z.parent.color=BLACK //case 3 z.parent.parent.color=RED Right-Rotate(T,z.parent.parent) <pre name="code" class="python"> else (same as "then" clause with right and left exchanged) //if a.parent==z.parent.parent.left,case 1,2,3with right and left exchangedT.ROOT.color=BLACK
红黑树的删除:
同样先定义一个移植算法:
def RB-Transplant(T,u,v): //用以v为根的子树替代以U为根的子树 if(u.parent==T.nil) T.ROOT=v else if(u==u.parent.left) u.parent.left=v else u.parent.right=v v.parent=u.parent
删除算法:
def RB-delete(T,z)y=z y-original-color=y.color if(z.left==T.nil)x=z.rightRB-Transplant(T,z,z.right)else if(z.right==T.nil)x=z.leftRB-Transplant(T,z,z.left)else y=Tree-min(z.right)y-original-color=y.colorx=y.rightif(y.parent==z)x.parent=y else RB-Transplant(T,y,y.right)y.right=z.righty.right.parent=y RB-Transplant(T,z,y)y.left=z.lefty.left.parent=y y.color=z.colorif(y-original-color==BLACK)RB-delete-fixup(T,x)
删除后的修复颜色属性操作
RB-delete-fixup(T,x):
def RB-delete-fixup(T,x) while(x!=T.ROOT&&x.color==BLACK) if(x==x.parent.left) w=x.parent.right if(w.color==RED) //case 1 w.color=BlACK x.parent.color=RED Left-Rotate(T,x.parent) w=x.parent.right if(w.left.color==BLACK&&w.right.color==BLACK) //case 2 w.color=RED x=x.parent else if(w.right.color==BLACK) //case 3 w.left.color=BLACK w.color=RED Right-Rotate(T,w) w=x.parent.right w.color=x.parent.color //case 4 x.parent.color=BLACK w.right.color=BLACK Left-Rotate(T,x.parent) x=T.ROOT else (same as "then" clause with right and left exchanged) x.color=BLACK
相关资料可见维基百科上关于红黑树的讲解
(ps:红黑树这块真是要把我弄晕了)
- 平衡二叉树各种算法详解一:红黑树
- 平衡二叉树算法详解
- 平衡二叉树算法详解
- 平衡二叉树算法详解
- 数据结构和算法一:平衡二叉树
- 算法-平衡二叉树
- 平衡二叉树 详解
- 详解平衡二叉树
- 平衡二叉树详解
- 平衡二叉树详解
- 平衡二叉树详解
- 平衡二叉树详解
- 二叉树的各种算法(一)python
- 十四周 项目一 验证算法(平衡二叉树)
- 第十四周 项目一 验证平衡二叉树相关算法
- 第十四周项目一 验证算法(平衡二叉树)
- 平衡二叉树算法分析
- 平衡二叉树算法分析
- 【SSH项目实战】国税协同平台-13.用户与角色关系
- java线程(一)
- NSDate的使用
- android屏幕问题
- Family
- 平衡二叉树各种算法详解一:红黑树
- scdn语法
- Hadoop — 分布式文件系统HDFS(初识 )
- hdu5522 Numbers
- HTML、XML、HTML5初识
- [sicily]1200. Stick
- 1、运行spark示例工程前期准备SparkExampleWorkSpace(1)
- 网页游戏研发巨头墨麟集团为什么会衰败的这么快?
- ThinkPHP中数据库CRUD操作方法盘点(field方法)