建立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. jquery中html()、text()、val()的区别

     (2013-03-26 10:49:16) 转载▼ 分类: jquery   .html()用为读取和修改元素的HTML标签 .text()用来读取或修改元素的纯文本内容 .val()用来读取或修改 ...

  2. requests+正则表达式 爬取 妹子图

    做了一个爬取妹子图某张索引页面的爬虫,主要用request和正则表达式. 感谢 崔庆才大神的 爬虫教学视频 和 gitbook: B站:https://www.bilibili.com/video/a ...

  3. Java中BufferedReader和scanner的对比

    Scanner 和BufferedReader同样能实现将键盘输入的数据送入程序, import java.io.*;import java.util.Scanner;public class C { ...

  4. 重装ubuntu

    重装前 需要备份软件.配置文件等,重装系统时,最好不要重新给/home分区,也不要格式化,要不你需要备份很多东西,重装后也需要做很多设置.也就是说/home不格式化,整个重装系统都是很快的.最多花10 ...

  5. 深入理解java虚拟机(十) Java 虚拟机运行时栈帧结构

    运行时栈帧结构 栈帧(Stack Frame) 是用于虚拟机执行时方法调用和方法执行时的数据结构,它是虚拟栈数据区的组成元素.每一个方法从调用到方法返回都对应着一个栈帧入栈出栈的过程. 每一个栈帧在编 ...

  6. Android-ContentProvider简单的增删改查

    注意:在ContentProvider里面写对数据库增删改查的时候,千万不能 db.close();  cursor.close(); 等操作,不然其他应用访问不到数据,也没有必要写isOpen(); ...

  7. mysql数据库使用sql查询数据库大小及表大小

    网上查了很多资料,最后发现一个可行的,分享如下: 数据库大小查询: select concat(round(sum(DATA_LENGTH/1024/1024),2),'M') from inform ...

  8. Oracle SQl优化总结

    对数据库技术的热爱是我唯一的安慰,毕竟这是自己喜欢的事情,还可以做下去. 因为客户项目的需要,我又开始接触Oracle,大部分工作在工作流的优化和业务数据的排查上.为了更好的做这份工作,我有参考过or ...

  9. Arcgis Android 手动搭建开发环境

    前言 本文为大家分享arcgis android 环境的手动搭建过程,默认你懂一定的java和android 基础知识,已经有android的开发环境.如缺乏以上环境和知识,请自行补充. 版本介绍 A ...

  10. 在JS中,将text框中数据格式化,根据不同的小数位数,格式化成对应的XXX,XXX,XXX.XX(2位小数) 或者XXX,XXX,XXX(0位小数)

    //在JS中,将text框中数据格式化,根据不同的小数位数,格式化成对应的XXX,XXX,XXX.XX(2位小数) 或者XXX,XXX,XXX(0位小数) function formatNum(num ...