# 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. Android手机使用广播监听手机收到的短信

    我们使用的Android手机在收到短信的时候会发出一条系统广播.该条广播中存放着接收到的短信的详细信息.本文将详细介绍如何通过动态注册广播来监听短信. 注册广播有两种方式,一种是动态注册,另一种是静态 ...

  2. Qemu编译qemu-system-arm

    /********************************************************************************* * Qemu编译qemu-syst ...

  3. c++跨文件变量声明

    常量是内部链接的,可以直接定义;  变量是外部链接,如果在头文件定义的话,如果出现多次引用同一个头文件的编译单元,就会引发multi redifine错误, 这个时候就要只是声明变量来解决:exter ...

  4. [LeetCode&Python] Problem 804. Unique Morse Code Words

    International Morse Code defines a standard encoding where each letter is mapped to a series of dots ...

  5. 了解 .NET 的默认 TaskScheduler 和线程池(ThreadPool)设置,避免让 Task.Run 的性能急剧降低

    .NET Framework 4.5 开始引入 Task.Run,它可以很方便的帮助我们使用 async / await 语法,同时还使用线程池来帮助我们管理线程.以至于我们编写异步代码可以像编写同步 ...

  6. arduino 配置 esp8266

    在连接之前,先把程序下载到arduino中,很简单,就是定义了软口.如果中间要改动程序,要把rx和tx的连线去掉,不然下载程序可能失败. ; ; void setup() { pinMode(rx,I ...

  7. M端计算rem方法

    (function(){var a=document.documentElement.clientWidth||document.body.clientWidth;if(a>460){a=460 ...

  8. Pma模块详解,对用户登录linux等进行限制,密码修改限制等

    PAM详细介绍 2014-04-02 09:26:41 标签:PAM 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://lidefu ...

  9. Tomcat:Several ports are already in use问题

    Several ports (8005, 8080, 8009) required by Tomcat v6.0 Server at localhost are already in use. The ...

  10. streamsets rest api 转换 graphql

    原理很简单,就是使用swagger api 生成schema 然后代理请求处理api 调用 参考项目 https://github.com/rongfengliang/streamsets-graph ...