AVL树Python实现
# 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实现的更多相关文章
- AVL树Python实现(使用递推实现添加与删除)
# coding=utf-8 # AVL树的Python实现(树的节点中包含了指向父节点的指针) def get_height(node): return node.height if node el ...
- AVL树的python实现
AVL树是带有平衡条件的二叉查找树,一般要求每个节点的左子树和右子树的高度最多差1(空树的高度定义为-1). 在高度为h的AVL树中,最少的节点数S(h)由S(h)=S(h-1)+S(h-2)+1得出 ...
- AVL树插入(Python实现)
建立AVL树 class AVLNode(object): def __init__(self,data): self.data = data self.lchild = None self.rchi ...
- python常用算法(5)——树,二叉树与AVL树
1,树 树是一种非常重要的非线性数据结构,直观的看,它是数据元素(在树中称为节点)按分支关系组织起来的结构,很像自然界中树那样.树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形 ...
- 【数据结构与算法Python版学习笔记】树——平衡二叉搜索树(AVL树)
定义 能够在key插入时一直保持平衡的二叉查找树: AVL树 利用AVL树实现ADT Map, 基本上与BST的实现相同,不同之处仅在于二叉树的生成与维护过程 平衡因子 AVL树的实现中, 需要对每个 ...
- AVL树探秘
本文首发于我的公众号 Linux云计算网络(id: cloud_dev) ,专注于干货分享,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,欢迎大家关注,二维码文末可以扫. 一.AV ...
- 详细理解平衡二叉树AVL与Python实现
前言 上一篇文章讨论的二叉搜索树,其时间复杂度最好的情况下是O(log(n)),但是最坏的情况是O(n),什么时候是O(n)呢? 像这样: 如果先插入10,再插入20,再插入30,再插入40就会成上边 ...
- 数据结构中的树(二叉树、二叉搜索树、AVL树)
数据结构动图展示网站 树的概念 树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合.它是由n(n>=1)个有限节点组成一个具有 ...
- 算法与数据结构(十一) 平衡二叉树(AVL树)
今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...
随机推荐
- Android手机使用广播监听手机收到的短信
我们使用的Android手机在收到短信的时候会发出一条系统广播.该条广播中存放着接收到的短信的详细信息.本文将详细介绍如何通过动态注册广播来监听短信. 注册广播有两种方式,一种是动态注册,另一种是静态 ...
- Qemu编译qemu-system-arm
/********************************************************************************* * Qemu编译qemu-syst ...
- c++跨文件变量声明
常量是内部链接的,可以直接定义; 变量是外部链接,如果在头文件定义的话,如果出现多次引用同一个头文件的编译单元,就会引发multi redifine错误, 这个时候就要只是声明变量来解决:exter ...
- [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 ...
- 了解 .NET 的默认 TaskScheduler 和线程池(ThreadPool)设置,避免让 Task.Run 的性能急剧降低
.NET Framework 4.5 开始引入 Task.Run,它可以很方便的帮助我们使用 async / await 语法,同时还使用线程池来帮助我们管理线程.以至于我们编写异步代码可以像编写同步 ...
- arduino 配置 esp8266
在连接之前,先把程序下载到arduino中,很简单,就是定义了软口.如果中间要改动程序,要把rx和tx的连线去掉,不然下载程序可能失败. ; ; void setup() { pinMode(rx,I ...
- M端计算rem方法
(function(){var a=document.documentElement.clientWidth||document.body.clientWidth;if(a>460){a=460 ...
- Pma模块详解,对用户登录linux等进行限制,密码修改限制等
PAM详细介绍 2014-04-02 09:26:41 标签:PAM 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://lidefu ...
- 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 ...
- streamsets rest api 转换 graphql
原理很简单,就是使用swagger api 生成schema 然后代理请求处理api 调用 参考项目 https://github.com/rongfengliang/streamsets-graph ...