# coding=utf-8
# AVL树Python实现 def get_height(node):
return node.height if node else -1 def tree_minimum(node):
temp_node = node
while temp_node.left:
temp_node = temp_node.left
return temp_node def tree_maximum(node):
temp_node = node
while temp_node.right:
temp_node = temp_node.right
return temp_node def left_left_rotate(node):
"""
AVL树的左左 其实跟红黑树的右旋没有区别 左左是两个节点均在左侧
最后一行的赋值是保证旋转的父节点的指针指向正确(虽然不知道有没有用 但是先试试吧)
:param node: 将要执行左左旋转的节点
:return: 左子节点
"""
node_left = node.left
node.left = node_left.right
node_left.right = node
node.height = max(get_height(node.left), get_height(node.right)) + 1
node_left.height = max(get_height(node_left.left), get_height(node_left.right)) + 1
return node_left def right_right_rotate(node):
"""
AVL树的右右 其实跟红黑树的左旋没有区别 右右是两个节点均在右侧
:param node: 将要执行右右旋转的节点
:return: 右子节点
"""
node_right = node.right
node.right = node_right.left
node_right.left = node
node.height = max(get_height(node.left), get_height(node.right)) + 1
node_right.height = max(get_height(node_right.left), get_height(node_right.right)) + 1
return node_right def left_right_rotate(node):
"""
AVL树的左右 -> 先左旋再右旋(红黑树) -> 右右然后左左(AVL树)
:param node: 出现高度异常的最高节点
:return: None
"""
node.left = right_right_rotate(node.left)
return left_left_rotate(node) def right_left_rotate(node):
node.right = left_left_rotate(node.right)
return right_right_rotate(node) def preorder_tree_walk(node):
if node:
print node.key
preorder_tree_walk(node.left)
preorder_tree_walk(node.right) class AVLTreeNode(object):
def __init__(self, key):
self.left = None
self.right = None
self.key = key
self.height = 0 class AVLTree(object):
def __init__(self):
self.root = None def find(self, key):
if not self.root:
return None
else:
return self._find(key) def _find(self, key):
start = self.root
while start:
if key == start.key:
return start
elif key > start.key:
start = start.right
elif key < start.key:
start = start.left
return None def insert(self, node):
if not self.root:
self.root = node
else:
self.root = self._insert(self.root, node) def _insert(self, index, node):
"""
AVL树插入操作的递归实现
:param index: root
:param node: 待插入节点
:return: root
"""
if not index:
index = node
elif node.key < index.key:
index.left = self._insert(index.left, node)
if get_height(index.left) - get_height(index.right) == 2:
if node.key < index.left.key:
index = left_left_rotate(index)
else:
index = left_right_rotate(index)
elif node.key > index.key:
index.right = self._insert(index.right, node)
if get_height(index.right) - get_height(index.left) == 2:
if node.key < index.right.key:
index = right_left_rotate(index)
else:
index = right_right_rotate(index)
index.height = max(get_height(index.left), get_height(index.right)) + 1
return index def delete(self, key):
self.root = self._delete(self.root, key) def _delete(self, index, key):
if not index:
raise KeyError, "Error, key not in the tree"
elif key < index.key:
index.left = self._delete(index.left, key)
if get_height(index.right) - get_height(index.left) == 2:
if get_height(index.right.right) > get_height(index.right.left):
index = right_right_rotate(index)
else:
index = right_left_rotate(index)
index.height = max(get_height(index.left), get_height(index.right))
elif key > index.key:
index.right = self._delete(index.right, key)
if get_height(index.left) - get_height(index.right) == 2:
if get_height(index.left.left) > get_height(index.left.right):
index = left_left_rotate(index)
else:
index = left_right_rotate(index)
index.height = max(get_height(index.left), get_height(index.right))
elif index.left and index.right:
if index.left.height <= index.right.height:
node_min = tree_minimum(index.right)
index.key = node_min.key
index.right = self._delete(index.right, index.key)
else:
node_max = tree_maximum(index.left)
index.key = node_max.key
index.left = self._delete(index.left, index.key)
index.height = max(get_height(index.left), get_height(index.right)) + 1
else:
if index.right:
index = index.right
else:
index = index.left
return index def main():
number_list = (7, 4, 1, 8, 5, 2, 9, 6, 3)
tree = AVLTree()
for number in number_list:
node = AVLTreeNode(number)
tree.insert(node)
preorder_tree_walk(tree.root)
tree.delete(4)
print '=========='
preorder_tree_walk(tree.root) if __name__ == '__main__':
main()

End.

AVL树Python实现的更多相关文章

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

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

  2. AVL树的python实现

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

  3. AVL树插入(Python实现)

    建立AVL树 class AVLNode(object): def __init__(self,data): self.data = data self.lchild = None self.rchi ...

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

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

  5. 【数据结构与算法Python版学习笔记】树——平衡二叉搜索树(AVL树)

    定义 能够在key插入时一直保持平衡的二叉查找树: AVL树 利用AVL树实现ADT Map, 基本上与BST的实现相同,不同之处仅在于二叉树的生成与维护过程 平衡因子 AVL树的实现中, 需要对每个 ...

  6. AVL树探秘

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev) ,专注于干货分享,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,欢迎大家关注,二维码文末可以扫. 一.AV ...

  7. 详细理解平衡二叉树AVL与Python实现

    前言 上一篇文章讨论的二叉搜索树,其时间复杂度最好的情况下是O(log(n)),但是最坏的情况是O(n),什么时候是O(n)呢? 像这样: 如果先插入10,再插入20,再插入30,再插入40就会成上边 ...

  8. 数据结构中的树(二叉树、二叉搜索树、AVL树)

    数据结构动图展示网站 树的概念 树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合.它是由n(n>=1)个有限节点组成一个具有 ...

  9. 算法与数据结构(十一) 平衡二叉树(AVL树)

    今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...

随机推荐

  1. I.MX6 Linux Qt 启动流程跟踪

    /************************************************************************** * I.MX6 Linux Qt 启动流程跟踪 ...

  2. Tempter of the Bone dfs+剪枝

    The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it u ...

  3. stenciljs 学习八 组件测试

    测试对于框架来说比较重要,对于web 组件的测试同样很重要,类似的jest 很方便,stenciljs也是基于jest 开发的 包含两个核心api render(), flush() 测试配置 pac ...

  4. Xamarin版的C# SVG路径解析器

    原文:Xamarin版的C# SVG路径解析器 Xamarin版的C# SVG路径解析器,对SVG的Path路径进行解析,其中包括: 主程序SvgPathParser.cs, 相关接口定义:ISour ...

  5. 4.图像sensor的特性和驱动解析

    修改 摄像头SDK中支持的sensor需要做的事 例如:ar0130 --> ov9712 1.修改加载load3518e脚本的参数 vi /etc/profile ./load3518e -i ...

  6. Queque 方法对比和分类

    添加类:方法 public boolean add(E e)      增加一个元索                     如果队列已满,则抛出一个IIIegaISlabEepeplian异常 bo ...

  7. 启动servlet报错:The servlets named [DemoServlet] and [main.java.com.wlf.demo.servlet.DemoServlet] are both mapped to the url-pattern [/hello] which is not permitted

    先看具体错误日志: [2019-04-26 09:29:25,484] Artifact demo-servlet:war: Artifact is being deployed, please wa ...

  8. SpringCloud初体验:六、利用 Sleuth 和 Zipkin 给微服务加上链路监控追踪查看功能

    首先:装上 Zipkin 服务,收集调用链跟踪数据,体验时装在了本机docker上, 方便快捷 docker run -d -p : openzipkin/zipkin 安装后访问地址也是 9411端 ...

  9. bat文件:启动,休眠VBox虚拟机

    1. start.Xp_Mysql.bat @echo cd D:\Program Files\VirtualBox\ D: .\VBoxManage startvm Xp_Mysql --type ...

  10. PHP常用函数总结(二):

    //=================图像处理=================================== //=================会话机制================== ...