红黑树的理解与使用
来源:互联网 发布:小米网络电视安装 编辑:程序博客网 时间:2024/05/17 08:26
what?
- 红黑树是一种二叉查找树,每个结点上会增加一个存储位表示结点的颜色,可以是RED与BLACK。
- 通过对任何一条从根到叶子的路径上各个结点的着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的。
红黑树的每个结点都有五个域:color、key、left、right和p。如果某结点没有一个子结点(叶子结点)或父结点(根结点),则相应的指针p域为值NIL。NIL视为指向二叉查找树的外结点(叶子)的指针,而把带关键字(key有值)的结点视为树的内结点。 - 红黑树的性质:
1)每个结点不是红的就是黑的
2)根结点是黑的
3)每个叶结点(NIL)是黑的
4)如果一个结点是红的,则它的两个儿子都是黑的
5)对每个结点,从该结点到其子孙结点的所有路径上包含相同个黑结点
why?
一棵高度为h的二叉查找树的操作:search、predecessor、successor、minimum、maximum、insert、delete的时间复杂度都是O(h)。而红黑树(red-black tree)是许多“平衡的”查找树中的一种,它能保证在最坏的情况下,基本的动态集合操作时间为O(lgn)。
how?
左旋
*************left-rotate(T,x)*****************y <- right[x] //x的右子树赋给y指针right[x] <- left[y] //y的左子树赋给x的右指针if left[y]!=nil[T] //如果y的左指针不指向空结点 then p[left[y]] <- x //x结点赋值给y左子树的父亲指针p[y] <- p[x] //x的父亲赋值给y的父亲指针if p[x] = nil[T] //如果x的父亲指针指向空结点 then root[T] <- y //根结点指针指向y结点else if x = left[p[x]] //如果x的父亲的左指针指向x结点(x是左子树) then left[p[x]] <- y //x的父亲的左指针指向y结点else right[p[x]] <- y //如果x的父亲的右指针指向x结点(x是右子树),x的父亲的右指针指向y结点left[y] <- x //y的左指针指向x结点p[x] <- y //x的父亲指针指向y结点
右旋
*****************right_rotate(T,x)*****************y <- left[x] //x的左子树赋值给y指针left[x] <- right[y] //y的右子树赋值给x的左指针if right[y] != nil[T] //如果y的右指针不指向空结点 then p[r[y]] <-x //x结点赋值给y的右子树的父亲指针if p[x] = nil[T] //如果x的父亲指针不指向空结点 then root[T] <- y //y结点赋值给T的根指针else if r[p[x]] = x //如果x的父亲的右指针指向x结点(x是右子树) then r[p[x]] <- y //y结点赋值给x的父亲的右指针else l[p[x]] <- y //如果x的父亲的左指针指向x结点(x是左子树),y结点赋值给x的父亲的左指针right[y] <- x //x赋值给y的右指针p[x] <- y //y赋值给x的父亲指针
插入
RB-INSERT(T,z)y <- nil[T] //空结点赋值给y指针x <- root[T] //根结点赋值给x指针while x != nil[T] //循环:x不指向空结点 do y <- x // x指向的结点赋值给y指针 if key[z] < key[x] // 如果需要插入的值比x结点的值小 then x <- left[x] // x指向结点的左结点赋值给x指针 else x <- right[x] // 否则x指向结点的右结点赋值给x指针p[z] <- y //y指向的结点赋值给z的父亲指针if y = nil[T] //如果空结点赋值给y指针 then root[T] <- z // z结点赋值给根指针 else if key[z] < key[y] // 如果z结点值小于y指向的结点的值 then left[y] <- z // z结点赋值给y指向的结点的左指针 else right[y] <- z // z结点赋值给y指向的结点的右指针left[z] <- nil[T] //空结点赋值给z结点的左指针right[z] <- nil[T] //空结点赋值给z结点的右指针color[z] <- RED //RED赋值给z结点的颜色指针RB-INSERT-FIXUP(T,z) //插入修复x指针是为了找到
插入修复
RB-INSERT-FIXUP(T,z)while color[p[z]] = RED do if p[z] = left[p[p[z]]] then y <- right[p[p[z]]] if color[y] = RED then color[p[z]] <- BLACK color[y] <- BLACK color[p[p[z]]] <- RED z <- p[p[z]] else if z = right[p[z]] then z <- p[z] LEFT-ROTATE(T,z) color[p[z]] <- BLACK color[p[p[z]]] <- RED RIGHT-ROTATE(T,p[p[z]]) else(same as then clause with "right" and "left" exchanged)color[root[T]] <- BLACK
删除
RB-DELETE(T,z)if left[z] = nil[T] or right[z] = nil[T] then y <- z else y <- TREE-SUCESSOR(z)if left[y] != nil[T] then x <- left[y] else x <- right[y]p[x] <- p[y]if p[y] = nil[T] then root[T] <- x else if y = left[p[y]] then left[p[y]] <- x else right[p[y]] <- xif y != z then key[z] <- key[y] copy y‘s satellite data into zif color[y] = BLACK then RB-DELETE-FIXUP(T,x)return y
删除修复
RB-DELETE-FIXUP(T,x)while x != root[T] and color[x] = BLACK do if x = left[p[x]] then w <- right[p[x]] if color[w] = RED then color[w] <- BLACK color[p[x]] <- RED LEFT-ROTATE(T,p[x]) w <- right[p[x]] if color[left[w]] = BLACK and color[right[w]] = BLACK then color[w] <- RED else if color[right[w]] = BLACK then color[left[w]] <- BLACK color[w] <- RED RIGHT-ROTATE(T,w) w <- right[p[x]] color[w] <- color[p[x]] color[p[x]] <- BLACK color[right[w]] <- BLACK LEFT-ROTATE(T,p[x]) x <- root[T] else(same as then clause with "right" and "left" exchanged)color[x] <- BLACK
虽然这些伪代码看起来生硬、难嚼,但是根据我之前的两段注释,相信就会容易理解一点。因为最近工作忙,之后,我会慢慢更新操作的图解,以及c++的实现代码。
阅读全文
0 0
- 红黑树的理解与使用
- 触发器的理解与使用
- tasklet的使用与理解
- ExecutorService 的理解与使用
- ExecutorService 的理解与使用
- AIDL的理解与使用
- documentHelper的理解与使用
- Executor的理解与使用
- WeakReference的理解与使用
- ExecutorService 的理解与使用
- memcached的理解与使用
- ContentProvider的理解与使用
- ExecutorService 的理解与使用
- ThreadLocal的理解与使用
- 队列的理解与使用
- WeakReference的理解与使用
- ExecutorService 的理解与使用
- ExecutorService 的理解与使用
- 使用 Flask-Cache 缓存给Flask提速
- 项目 1- C/C++语言中函数参数传递的三种方式
- C++之内联函数
- Spring Boot中使用Redis数据库
- 88. Merge Sorted Array
- 红黑树的理解与使用
- 【Unity】UGUI Image组件检视面板编辑器扩展(ImageEditor类)
- 什么是ESR
- rsync命令 远程数据同步工具
- 第三周——项目三—求集合并集
- QMainWindow
- 机器学习算法-朴素贝叶斯
- SQL SELECT 语句
- java点餐系统