建立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实现)的更多相关文章

  1. AVL树插入和删除

    一.AVL树简介 AVL树是一种平衡的二叉查找树. 平衡二叉树(AVL 树)是一棵空树,或者是具有下列性质的二叉排序树:    1它的左子树和右子树都是平衡二叉树,    2且左子树和右子树高度之差的 ...

  2. AVL树插入操作实现

    为了提高二插排序树的性能,规定树中的每个节点的左子树和右子树高度差的绝对值不能大于1.为了满足上面的要求需要在插入完成后对树进行调整.下面介绍各个调整方式. 右单旋转 如下图所示,节点A的平衡因子(左 ...

  3. AVL树的python实现

    AVL树是带有平衡条件的二叉查找树,一般要求每个节点的左子树和右子树的高度最多差1(空树的高度定义为-1). 在高度为h的AVL树中,最少的节点数S(h)由S(h)=S(h-1)+S(h-2)+1得出 ...

  4. AVL树Python实现(使用递推实现添加与删除)

    # coding=utf-8 # AVL树的Python实现(树的节点中包含了指向父节点的指针) def get_height(node): return node.height if node el ...

  5. AVL树Python实现

    # coding=utf-8 # AVL树Python实现 def get_height(node): return node.height if node else -1 def tree_mini ...

  6. AVL树的插入与删除

    AVL 树要在插入和删除结点后保持平衡,旋转操作必不可少.关键是理解什么时候应该左旋.右旋和双旋.在Youtube上看到一位老师的视频对这个概念讲解得非常清楚,再结合算法书和网络的博文,记录如下. 1 ...

  7. python常用算法(5)——树,二叉树与AVL树

    1,树 树是一种非常重要的非线性数据结构,直观的看,它是数据元素(在树中称为节点)按分支关系组织起来的结构,很像自然界中树那样.树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形 ...

  8. My集合框架第三弹 AVL树

    旋转操作: 由于任意一个结点最多只有两个儿子,所以当高度不平衡时,只可能是以下四种情况造成的: 1. 对该结点的左儿子的左子树进行了一次插入. 2. 对该结点的左儿子的右子树进行了一次插入. 3. 对 ...

  9. 深入浅出数据结构C语言版(12)——平衡二叉查找树之AVL树

    在上一篇博文中我们提到了,如果对普通二叉查找树进行随机的插入.删除,很可能导致树的严重不平衡 所以这一次,我们就来介绍一种最老的.可以实现左右子树"平衡效果"的树(或者说算法),即 ...

随机推荐

  1. [欣赏代码片段] (JavaScript) Responsive jQuery

    jQuery(document).ready(function($) { /* getting viewport width*/ var responsive_viewport = $(window) ...

  2. ConfigureAwait(false)避免上下文延续

    之前MVC利用MvcHtmlString封装通用下拉菜单,菜单数据需要从webapi获取,自然用到了 await Http Client.GetAsync(Url)方法,前端 @Html.Select ...

  3. 【转】jvm 堆内存 栈内存 大小设置

    原文地址:http://blog.csdn.net/qh_java/article/details/46608395 4种方式配置不同作用域的jvm的堆栈内存! 1.Eclise 中设置jvm内存: ...

  4. Sweetkang 的机器学习实验室 (1)

    前言 近年来,Machine Learning 在许多领域上已然取得了可喜的成就,非常火热.就我个人来讲,有意将业余 Sport Programming 的范围扩展一下,譬如 Topcoder Mar ...

  5. 构造复杂Lambda困惑之学会用LinqPad和Linqer实现Sql 和 Lambda之间的互转

    一:linq的话我们可能会遇到两个问题: 1. 我们的linq出现性能低下的时候,如果优化???? 我们写的linq所生成的sql是无法控制的... (要做性能优化,必须预先知道sql会生成啥样的?? ...

  6. 新入门PGSQL数据库(尝试利用PGPOOL实现分布式),摘录笔记

    概念: PostgreSQL (pronounced "post-gress-Q-L") is an open source relational database managem ...

  7. Replication--分区+复制

    1>配置订阅表使用分区,在发布的项目属性中设置"复制分区方案"和"复制索引分区方案"为true,然后初始化订阅 2>在发布数据库上修改发布属性 -- ...

  8. Qt keyPressEvent keyReleaseEvent 分析

    最近使用Qt时,在增加一个按下某键(M),临时显示图层,键(M)弹起时隐藏图层的功能时,碰到了一些问题: keyPressEvent 事件不响应 这个问题,网上搜到的结果是可能是控件没获取焦点,比如Q ...

  9. Nagios+InfluxDB+Grafana

    1. 概述 Nagios负责收集数据,是一款开源的免费网络监视工具. influxDB负责存储数据,是一个开源的时间序列数据库.比较适合存储监控或者部署记录这些时序数据. Grafana负责数据的图形 ...

  10. NOIP提高组题目归类+题解摘要(2008-2017)

    因为前几天作死立了一个flag说要把NOIP近十年的题目做一做,并写一个题目归类+题解摘要出来,所以这几天就好好的(然而还是颓废了好久)写了一些这些往年的NOIP题目. 这篇博客有什么: 近十年NOI ...