红黑树-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 ...
随机推荐
- 在Ubuntu下编译Assimp库
在Ubuntu下编译Assimp库 怎样在Ubuntu下编译Assimp库?这是我曾经编译成功后做的笔记,供參考. 1.去以下的站点去下载Assimp库: http://assimp.sourcefo ...
- MongoDB shell操作
shell命令操作语法和JavaScript很类似,其实控制台底层的查询语句都是用JavaScript脚本完成操作的.使用shell 命令,需要启动mongo.exe. 常用shell命令如下: 1. ...
- Cloudera Hadoop 5& Hadoop高阶管理及调优课程(CDH5,Hadoop2.0,HA,安全,管理,调优)
1.课程环境 本课程涉及的技术产品及相关版本: 技术 版本 Linux CentOS 6.5 Java 1.7 Hadoop2.0 2.6.0 Hadoop1.0 1.2.1 Zookeeper 3. ...
- hive udaf 用maven打包运行create temporary function 时报错
用maven打包写好的jar,在放到hive中作暂时函数时报错. 错误信息例如以下: hive> create temporary function maxvalue as "com. ...
- Effective C++_笔记_条款09_绝不在构造和析构过程中调用virtual函数
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为方便采用书上的例子,先提出问题,在说解决方案. 1 问题 1: ...
- Python金融应用编程(数据分析、定价与量化投资)
近年来,金融领域的量化分析越来越受到理论界与实务界的重视,量化分析的技术也取得了较大的进展,成为备受关注的一个热点领域.所谓金融量化,就是将金融分析理论与计算机编程技术相结合,更为有效的利用现代计算技 ...
- 基于visual Studio2013解决C语言竞赛题之1093连接链表
题目 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <math.h> #i ...
- hdu 4707 搜索 目前做的最水的搜索
直接深搜 ,水啊 #include<cstdio> #include<cstring> #include<algorithm> using namespace s ...
- Codeforces Round #197 (Div. 2) D. Xenia and Bit Operations
D. Xenia and Bit Operations time limit per test 2 seconds memory limit per test 256 megabytes input ...
- 树莓派学习笔记——使用文件IO操作GPIO SysFs方式
0 前言 本文描写叙述假设通过文件IO sysfs方式控制树莓派 GPIO端口.通过sysfs方式控制GPIO,先訪问/sys/class/gpio文件夹,向export文件写入GPIO编号, ...