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 ...
随机推荐
- Eclipse Error: The refactoring does not change any source code
最近在做android项目的过程中遇到这样一个问题,新增一个activity的时候添加不成,eclipse提示The refactoring does not change any source co ...
- stdlib.h
stdlib 头文件即standard library标准库头文件.stdlib.h里面定义了五种类型.一些宏和通用工具函数. 1 类型例如size_t.wchar_t.div_t.ldiv_t和ll ...
- stm32 定时器TIM时钟步骤
1)TIM3 时钟使能 . RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIMx, ENABLE); //时钟使能 2) 初始化定时器参数,设置自动重装值, 分频系数, ...
- win8转win7+真正解决 “安装程序无法定位现有系统分区,也无法创建新的系统分区”的方法
问题情况:win8电脑转win7系统,出现问题:“安装程序无法定位现有系统分区,也无法创建新的系统分区” 第一种:猜测可行的方法: 1.老毛桃U盘启动电脑,进入PE系统后,直接使用Diskgeni ...
- Pr学习日记
1.http://tieba.baidu.com/p/4102775256 2.素才,编辑制作视频,视频输出 3. 启用新建保存: 启用:双击 新建项目:名称(第一节课),位置 ...
- 20155224 2016-2017-2 《Java程序设计》第5周学习总结
20155224 2016-2017-2 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 Java中的错误都会被打包为对象,可以尝试(try)捕捉(catch)代表错误的对象 ...
- Executor 框架详解
框架最核心的类是ThreadPoolExecutor,它是Java线程池的实现类,通过Executors工具类,可以创建3种类型的ThreadPoolExecutor: 首先附上ThreadPoolE ...
- 51Nod:1268 和为K的组合
1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 给出N个正整数组成的数组A,求能否从中选出若干个,使他们的和为K.如果可以 ...
- codeforces 724c Ray Tracing
好题 原题: There are k sensors located in the rectangular room of size n × m meters. The i-th sensor is ...
- ppt标题排版