AVL树插入(Python实现)
建立AVL树
class AVLNode(object):
def __init__(self,data):
self.data = data
self.lchild = None
self.rchild = None
self.parent = None
self.bf = 0 class AVLTree(object)
def __init__(self,li=None)
self.root = None
if li:
for val in li:
self.insert(self.root,val) def insert(self,node,val):
if not node:
node = AVLNode(val)
elif val < node.data:
node.lchild = self.insert(node.lchild,val)
node.lchild.parent = node
elif val > node.data:
node.rchild = self.insert(node.rchild,val)
node.rchild.parent = node
return node
左旋转、右旋转
def rorate_left(self,p,c):
s2 = c.lchild
p.rchild = s2
if s2:
s2.parent = p
c.lchild = p
p.parent = c
p.bf = 0
c.bf = 0
return c def rorate_right(self,p,c):
s2 = c.rchild
p.lchild = s2
if s2:
s2.parent
c.rchild = p
p.parent = c
p.bf = 0
c.bf = 0
return c
右→左旋转、左→右旋转
def rotate_right_left(self,p,c):
g = c.lchild #右旋
s3 = g.rchild #1.把右孩子拿出来
c.lchild = s3 #2.右孩子交给 C
if s3:
s3.parent = c
g.rchild = c #3.链接右孩子
c.parent = g #4.链接父结点 #左旋
s2 = g.lchild
p.rchild = s2
if s2:
s2.parent = p
g.lchild = p
p.parent = g #更新bf
if g.bf > 0: #插入到s3 #是指刚插入节点的g的平衡值
p.bf = -1
c.bf = 0
elif g.bf < 0: #插入到s2
p.bf = 0
c.bf = 1
else: #插入的是G本身
p.bf = 0
c.bf = 0
g.bf = 0
return g def rotate_left_right(self,p,c):
g = c.rchild #左旋
s2 = g.lchild
c.rchild = s2
if s2:
s2.parent = c
g.lchild = c
c.parent = g #右旋
s3 = g.rchild
p.lchild = s3
if s3:
s3.parent = p
g.rchild = p
p.parent = g #更新bf
if g.bf < 0: #插入到s2
p.bf = 1
c.bf = 0
elif g.bf > 0: #插入到s3
p.bf = 0
c.bf = -1
else: #插入的是G本身
p.bf = 0
c.bf = 0
g.bf = 0
return g
插入
def insert_no_rec(self,val):
#1.插入
p = self.root
if not p:
self.root = AVLNode(val)
return
while True:
if val < p.data:
if p.lchild: #左孩子存在
p = p.lchild
else: #左孩子不存在
p.lchild = AVLNode(val)
p.lchild.parent = p
node = p.lchild #node 存储的就是插入的节点
break
else val > p.data:
if p.rchild:
p = p.rchild
else:
p.rchild = AVLNode(val)
p.rchild.parent = p
node = p.rchild
break
else: #等于 #同样的元素不多次插入
#avl尽量不允许两个相同的数插入
return #2.更新balance factor
while node.parent: #node.parent 不为空时
if node.parent.lchild == node: #传递节点是在左子树,左子树更沉了
#第一乱循环,更新node.parent的bf -= 1
if node.parent.bf < 0: #原来node.parent.bf == -1 (更新后会变成-2)
# 做旋转
# 看node哪边沉
head = node.parent.parent #为了链接旋转之后的子树
tmp = node.parent #旋转前的子树的根
if node.bf > 0:
n = self.rotate_left_right(node.parent,node)
else:
n = self.rorate_right(node.parent,node)
elif node.parent.bf > 0: #原来node.parent.bf == 1 (更新后变成0)
node.parent.bf = 0 #平衡,即可以不需要确认父亲节点
break
else: #原来node.parent.bf = 0,更新之后变成-1
node.parent.bf = -1
node = node.parent
continue
else: #传递节点是在右子树,右子树更沉了
if node.parent.bf > 0:
head = node.parent.parent
tmp = node.parent
if node.bf < 0:
n = self.rotate_right_left(node.parent,node)
else:
n = self.rorate_left(node.parent,node)
elif node.parent.bf < 0:
node.parent.bf = 0
break
else:
node.parent.bf = 1
node = node.parent
continue #3.链接旋转后的子树(只有做了旋转之后才会到这一步)
n.parent = head
if head: #head不是空
if tmp == head.lchild:
head.lchild = n
else:
head.rchild = n
break
else:
self.root = n
break
AVL树插入(Python实现)的更多相关文章
- AVL树插入和删除
一.AVL树简介 AVL树是一种平衡的二叉查找树. 平衡二叉树(AVL 树)是一棵空树,或者是具有下列性质的二叉排序树: 1它的左子树和右子树都是平衡二叉树, 2且左子树和右子树高度之差的 ...
- AVL树插入操作实现
为了提高二插排序树的性能,规定树中的每个节点的左子树和右子树高度差的绝对值不能大于1.为了满足上面的要求需要在插入完成后对树进行调整.下面介绍各个调整方式. 右单旋转 如下图所示,节点A的平衡因子(左 ...
- AVL树的python实现
AVL树是带有平衡条件的二叉查找树,一般要求每个节点的左子树和右子树的高度最多差1(空树的高度定义为-1). 在高度为h的AVL树中,最少的节点数S(h)由S(h)=S(h-1)+S(h-2)+1得出 ...
- AVL树Python实现(使用递推实现添加与删除)
# coding=utf-8 # AVL树的Python实现(树的节点中包含了指向父节点的指针) def get_height(node): return node.height if node el ...
- AVL树Python实现
# coding=utf-8 # AVL树Python实现 def get_height(node): return node.height if node else -1 def tree_mini ...
- AVL树的插入与删除
AVL 树要在插入和删除结点后保持平衡,旋转操作必不可少.关键是理解什么时候应该左旋.右旋和双旋.在Youtube上看到一位老师的视频对这个概念讲解得非常清楚,再结合算法书和网络的博文,记录如下. 1 ...
- python常用算法(5)——树,二叉树与AVL树
1,树 树是一种非常重要的非线性数据结构,直观的看,它是数据元素(在树中称为节点)按分支关系组织起来的结构,很像自然界中树那样.树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形 ...
- My集合框架第三弹 AVL树
旋转操作: 由于任意一个结点最多只有两个儿子,所以当高度不平衡时,只可能是以下四种情况造成的: 1. 对该结点的左儿子的左子树进行了一次插入. 2. 对该结点的左儿子的右子树进行了一次插入. 3. 对 ...
- 深入浅出数据结构C语言版(12)——平衡二叉查找树之AVL树
在上一篇博文中我们提到了,如果对普通二叉查找树进行随机的插入.删除,很可能导致树的严重不平衡 所以这一次,我们就来介绍一种最老的.可以实现左右子树"平衡效果"的树(或者说算法),即 ...
随机推荐
- [C++] 2D Array's memory allocation
2D Array's memory allocation
- wins 软件安装
1.x86 x64区别86就是原来的32位操作系统64就是现在比较新的64位操作系统
- mysql 事物ACID和隔离级别
⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则 ...
- Memcached在Windows下的配置和使用(转)
出处:http://www.cnblogs.com/sunniest/p/4154209.html Memcached学习笔记---- 安装和配置 首先,下载Memcached相关文件. 打开控制台, ...
- 两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试)
本篇文章主要介绍了"两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试)",主要涉及到两款JSON类库Jackson与JSON-lib的性能对比(新增第三款 ...
- OpenCV实现pHash哈希
离散余弦变换(DCT,Discrete Cosine Transform)是与傅里叶变换相关的一种变换,它类似于离散傅里叶变换(DFT,Discrete Fourier Transform),但是只使 ...
- 流程控制语句(if、for、while、do while、switch、 break、continue)
3:流程控制语句 (1)顺序结构 从上往下,依次执行 (2)选择结构 按照不同的选择,执行不同的代码 (3)循环结构 做一些重复的代码 4:if语句 (1)三种格式 ...
- js代码定义类代码的领悟
var Class = { create: function() { return function() { this.initialize.apply(this, argumen ...
- Arduino I2C + 三轴加速度计ADXL345
ADXL345是ADI公司生产的三轴数字加速度计芯片,与ST的LIS3DH功能接近.主要特性有: 工作电压:2.0 ~ 3.6V 功耗:待机功耗0.1μA:工作时与数据输出频率(ODR)有关,如ODR ...
- .NET WCF Return String 字符串有反斜杠的处理
应该是: {"Message":"Hello World"} 结果是:" {\"Message\":\"Hello Wo ...