红黑树-Python实现
#coding:utf8
#author:HaxtraZ
#description:红黑树,python实现 RED = 'red'
BLACK = 'black' class RBT:
def __init__(self):
self.items = []
self.root = None def LEFT_ROTATE(self, x):
# x是一个RBTnode
y = x.right
if y is None:
# 右节点为空,不旋转
return
else:
beta = y.left
x.right = beta
if beta is not None:
beta.parent = x p = x.parent
y.parent = p
if p is None:
# x原来是root
self.root = y
elif x == p.left:
p.left = y
else:
p.right = y
y.left = x
x.parent = y def RIGHT_ROTATE(self, y):
# y是一个节点
x = y.right
if x is None:
# 右节点为空,不旋转
return
else:
beta = x.right
y.left = beta
if beta is not None:
beta.parent = y p = y.parent
x.parent = p
if p is None:
# y原来是root
self.root = x
elif y == p.left:
p.left = x
else:
p.right = x
x.right = y
y.parent = x def INSERT(self, val):
z = RBTnode(val)
y = None
x = self.root
while x is not None:
y = x
if z.val < x.val:
x = x.left
else:
x = x.right z.PAINT(RED)
z.parent = y if y is None:
# 插入z之前为空的RBT
self.INSERT_FIXUP(z) elif y.color == RED:
# z的父节点y为红色,需要fixup。
# 如果z的父节点y为黑色,则不用调整
if z.val < y.val:
y.left = z
else:
y.right = z
self.INSERT_FIXUP(z) def INSERT_FIXUP(self, z):
# case 1:z为root节点
if self.root == None:
z.PAINT(BLACK)
self.root = z
return # case 2:z的父节点为黑色
if self.parent.color == BLACK:
# 包括了z处于第二层的情况
return # 下面的几种情况,都是z.parent.color == RED:
# 节点y为z的uncle
p = z.parent
if p == p.parent.left:
y = p.parent.right
else:
y = p.parent.left g = p.parent # g为x的grandpa
# case 3-0:z没有叔叔。即:y为NIL节点
# 注意,此时z的父节点一定是RED
if y is None:
if z == p.left:
# 3-0-0:z为右儿子,则把p左旋
# 转化为3-0-1或3-0-2的情况
self.LEFT_ROTATE(p)
p, z = z, p
g.PAINT(RED)
p.PAINT(BLACK)
if g.left == p:
# 3-0-1:p为g的左儿子
self.RIGHT_ROTATE(g)
else:
# 3-0-2:p为g的右儿子
self.LEFT_ROTATE(g) # case 3-1:z有黑叔
elif y.color == BLACK:
if p.right == z:
# 3-1-0:z为右儿子,则左旋p
# 转化为3-1-1或3-1-2
self.LEFT_ROTATE(p)
p, z = z, p p.PAINT(BLACK)
g.PAINT(RED)
if p == g.left:
# 3-1-1:p为g的左儿子,则右旋g
self.RIGHT_ROTATE(g)
else:
# 3-1-2:p为g的右儿子,则左旋g
self.LEFT_ROTATE(g) # case 3-2:z有红叔
# 则涂黑父和叔,涂红爷,g作为新的z,递归调用
else:
y.PAINT(BLACK)
p.PAINT(BLACK)
g.PAINT(RED)
self.INSERT_FIXUP(g) def DELETE(self, val):
curNode = self.root
while curNode is not None:
if val < curNode.val:
curNode = curNode.left
elif val > curNode.val:
curNode = curNode.right
else:
# 找到了值为val的元素,正式开始删除 if curNode.left is None and curNode.right is None:
# case1:curNode为叶子节点:直接删除即可
if curNode == self.root:
self.root = None
else:
p = curNode.parent
if curNode == p.left:
p.left = None
else:
p.right = None elif curNode.left is not None and curNode.right is not None:
sucNode = self.SUCCESOR(curNode)
curNode.val, sucNode.val = sucNode.val, curNode.val
self.DELETE(sucNode.val) else:
p = curNode.parent
if curNode.left is None:
x = curNode.right
else:
x = curNode.left
if curNode == p.left:
p.left = x
else:
p.right = x
x.parent = p
if curNode.color == BLACK:
self.DELETE_FIXUP(x) curNode = None return False def FIND(self, val): class RBTnode:
'''红黑树的节点类型'''
def __init__(self, val):
self.val = val
self.left = None
self.right = None
self.parent = None del PAINT(self, color):
self.color = colro
红黑树-Python实现的更多相关文章
- 红黑树Python实现
# coding=utf-8 # 红黑树Python实现 # 颜色常量 RED = 0 BLACK = 1 def left_rotate(tree, node): if not node.right ...
- 红黑树:个人理解与Python实现
红黑树:个人理解与Python实现 [基本事实1] 红黑树是一种平衡的二叉查找树,无论插入还是删除操作都可以在O(lg n)内实现,而一般的二叉查找树则在极端情况下会退化为线性结构.红黑树之所以是平衡 ...
- 算法导论 第十三章 红黑树(python)-1插入
红黑树是上一章二叉搜索树的改进,实现一种平衡 ,保证不会出现二叉树变链表的情况,基本动态集合操作的时间复杂度为O(lgn) 实际用途:c++stl中的set,map是用他实现的 红黑树的性质: 1.每 ...
- 彻底理解红黑树及JavaJDK1.8TreeMap源码分析
1. 定义 红黑树也是二叉查找树,我们知道,二叉查找树这一数据结构并不难,而红黑树之所以难是难在它是自平衡的二叉查找树,在进行插入和删除等可能会破坏树的平衡的操作时,需要重新自处理达到平衡状态.红黑树 ...
- Java实现红黑树(平衡二叉树)
前言 在实现红黑树之前,我们先来了解一下符号表. 符号表的描述借鉴了Algorithms第四版,详情在:https://algs4.cs.princeton.edu/home/ 符号表有时候被称为字典 ...
- 红黑树——算法导论(15)
1. 什么是红黑树 (1) 简介 上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...
- jdk源码分析红黑树——插入篇
红黑树是自平衡的排序树,自平衡的优点是减少遍历的节点,所以效率会高.如果是非平衡的二叉树,当顺序或逆序插入的时候,查找动作很可能会遍历n个节点 红黑树的规则很容易理解,但是维护这个规则难. 一.规则 ...
- 谈c++ pb_ds库(二) 红黑树大法好
厉害了,没想到翻翻pb_ds库看到这么多好东西,封装好的.现成的splay.红黑树.avl... 即使不能在考场上使用也可以用来对拍哦 声明/头文件 #include <ext/pb_ds/tr ...
- 定时器管理:nginx的红黑树和libevent的堆
libevent 发生超时后, while循环一次从堆顶del timer——直到最新调整的最小堆顶不是超时事件为止,(实际是del event),但是会稍后把这个timeout的 event放到ac ...
随机推荐
- [hadoop系列]Pig的安装和简单演示样例
inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish ).(来源:http://blog.csdn.net/inkfish) Pig是Yaho ...
- linux命令:Linux命令大全
Linux命令大全 http://man.linuxde.net/
- Windows Azure入门教学系列 (九):Windows Azure 诊断功能
本文是Windows Azure入门教学的第九篇文章. 本文将会介绍如何使用Windows Azure 诊断功能.跟部署在本地服务器上的程序不同,当我们的程序发布到云端之后,我们不能使用通常的调试方法 ...
- javascript 中 事件流和事件冒泡
一.事件流 是描述页面接受事件的顺序,IE 使用的是时间冒泡流;而Netscape的事件采用的是事件捕获流.1.事件冒泡JS 和 HTML是通过事件的方式实现交互.事件冒泡 开始元素,将事件逐级传递, ...
- django admin manytomany获取所选字段值
和一般views中前端数据的获取一样. def save_model(self, request, obj, form, change): door_id_list= request. ...
- CSDN改版问题多多
刚刚上CSDN,发现改版了,推出C币功能. 然后看了2分钟,发现了一个Bug,于是准备提交到论坛.但是--居然提交Bug的论坛也出现Bug.印象中,每次CSDN更新版本号Bug都非常多,这,作为程序猿 ...
- 让Delphi XE2程序支持UAC
在win7下,开发的程序有的时候莫名其妙就不能正常工作了,其实都是因为权限不够,要想能够正常运行,就需要获得管理员权限,这就需要处理UAC.具体方法如下: 一,制作“uac.manifest”文件.新 ...
- js / ajax 成功提交后怎么跳转到另外一个页面?
把success那段改成 success : function (r) { if ( r.status == 'error' ){ alert(msg[r.msgno]); } else if (r. ...
- 基于visual Studio2013解决面试题之0208二叉搜索树后序遍历序列
题目
- KMP poj
题目来自:http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2315188.html KMP算法开始是判断字符串b是否是字符串a的子串,朴素的算法是枚举 ...