AVL树Python实现(使用递推实现添加与删除)
# coding=utf-8
# AVL树的Python实现(树的节点中包含了指向父节点的指针) def get_height(node):
return node.height if node else -1 def get_maximum(node):
temp_node = node
while temp_node.right:
temp_node = temp_node.right
return temp_node def get_minimum(node):
temp_node = node
while temp_node.left:
temp_node = temp_node.left
return temp_node def preorder_tree_walk(node):
if node:
print node.key, node.height
preorder_tree_walk(node.left)
preorder_tree_walk(node.right) def left_left_rotate(tree, node):
# 先将 node 和 node_left 之间及其左右节点赋值 (node_left.left node.right 保持不变)
node_left = node.left
node.left = node_left.right
node_left.right = node
if not node.p:
tree.root = node_left
node_left.p = None
elif node == node.p.left:
node.p.left = node_left
node_left.p = node.p
elif node == node.p.right:
node.p.right = node_left
node_left.p = node.p
node.p = node_left
while node:
node.height = max(get_height(node.left), get_height(node.right)) + 1
node = node.p def right_right_rotate(tree, node):
node_right = node.right
node.right = node_right.left
node_right.left = node
if not node.p:
tree.root = node_right
node_right.p = None
elif node == node.p.left:
node.p.left = node_right
node_right.p = node.p
elif node == node.p.right:
node.p.right = node_right
node_right.p = node.p
node.p = node_right
while node:
node.height = max(get_height(node.left), get_height(node.right)) + 1
node = node.p def left_right_rotate(tree, node):
right_right_rotate(tree, node.left)
left_left_rotate(tree, node) def right_left_rotate(tree, node):
left_left_rotate(tree, node.right)
right_right_rotate(tree, node) class AVLTreeNode(object):
def __init__(self, key):
self.key = key
self.p = None
self.left = None
self.right = None
self.height = 0 class AVLTree(object):
def __init__(self):
self.root = None def search(self, key):
if not self.root:
return None
else:
return self._search(key) def _search(self, key):
start = self.root
while start:
if key < start.key:
start = start.left
elif key > start.key:
start = start.right
else:
return start
return None def insert(self, node):
temp_root = self.root
temp_node = None
# 找到要插入的父节点(temp_node)
while temp_root:
temp_node = temp_root
if node.key < temp_node.key:
temp_root = temp_root.left
elif node.key > temp_node.key:
temp_root = temp_root.right
else:
raise KeyError, "Error!" # 如果父节点为空 则说明这是一个空树 把 root 赋值即可
if not temp_node:
self.root = node
elif node.key < temp_node.key:
temp_node.left = node
node.p = temp_node
temp_node.height = max(get_height(temp_node.left), get_height(temp_node.right)) + 1
temp_p = temp_node.p
while temp_p:
temp_p.height = max(get_height(temp_p.left), get_height(temp_p.right)) + 1
temp_p = temp_p.p
elif node.key > temp_node.key:
temp_node.right = node
node.p = temp_node
temp_node.height = max(get_height(temp_node.left), get_height(temp_node.right)) + 1
temp_p = temp_node.p
while temp_p:
temp_p.height = max(get_height(temp_p.left), get_height(temp_p.right)) + 1
temp_p = temp_p.p
self.fixup(node) def fixup(self, node):
if node == self.root:
return
while node:
if get_height(node.left) - get_height(node.right) == 2:
if node.left.left:
left_left_rotate(self, node)
else:
left_right_rotate(self, node)
break
elif get_height(node.right) - get_height(node.left) == 2:
if node.right.right:
right_right_rotate(self, node)
else:
right_left_rotate(self, node)
break
node = node.p def delete(self, key):
temp_node = self.root
while temp_node:
if key > temp_node.key:
temp_node = temp_node.right
elif key < temp_node.key:
temp_node = temp_node.left
else:
break
if not temp_node:
return False
elif temp_node.left and temp_node.right:
if get_height(temp_node.left) > get_height(temp_node.right):
# 注意删除的时候不是直接把左右子树往上提 而是分别找到左右子树中的最大值和最小值往上提
# 由于是最大子节点 故一定没有右子
node_max = get_maximum(temp_node.left)
if node_max.left:
node_max_p = node_max.p
node_max_p.right = node_max.left
node_max.left.p = node_max_p
node_max.right = temp_node.right
temp_node.right.p = node_max
node_max.left = temp_node.left
temp_node.left.p = node_max
if temp_node.p:
if temp_node == temp_node.p.left:
temp_node.p.left = node_max
node_max.p = temp_node.p
else:
temp_node.p.right = node_max
node_max.p = temp_node.p
else:
self.root = node_max
node_max.p = None
temp_node = node_max
else:
node_min = get_minimum(temp_node.right)
if node_min.right:
node_min_p = node_min.p
node_min_p.left = node_min.right
node_min.right.p = node_min_p
node_min.left = temp_node.left
temp_node.left.p = node_min
node_min.right = temp_node.right
temp_node.right.p = node_min
if temp_node.p:
if temp_node == temp_node.p.left:
temp_node.p.left = node_min
node_min.p = temp_node.p
else:
temp_node.p.right = node_min
node_min.p = temp_node.p
else:
self.root = node_min
node_min.p = None
temp_node = node_min
temp_node.height = max(get_height(temp_node.left), get_height(temp_node.right)) + 1
self.fixup(temp_node) 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 else -1 def tree_mini ...
- Python实现单链表数据的添加、删除、插入操作
Python实现单链表数据的添加.删除.插入操作 链表的定义: 链表(linked list)是由一组被称为结点的数据元素组成的数据结构,每个结点都包含结点本身的信息和指向下一个结点的地址.由于每个结 ...
- Python可迭代对象中的添加和删除(add,append,pop,remove,insert)
list: classmates = ['Michael', 'Bob', 'Tracy'] classmates.append('Adam') //添加在末尾,没有add()方法 classmate ...
- 平衡二叉树,AVL树之图解篇
学习过了二叉查找树,想必大家有遇到一个问题.例如,将一个数组{1,2,3,4}依次插入树的时候,形成了图1的情况.有建立树与没建立树对于数据的增删查改已经没有了任何帮助,反而增添了维护的成本.而只有建 ...
- 图解:平衡二叉树,AVL树
学习过了二叉查找树,想必大家有遇到一个问题.例如,将一个数组{1,2,3,4}依次插入树的时候,形成了图1的情况.有建立树与没建立树对于数据的增删查改已经没有了任何帮助,反而增添了维护的成本.而只有建 ...
- 数据结构图文解析之:AVL树详解及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- AVL树(三)之 Java的实现
概要 前面分别介绍了AVL树"C语言版本"和"C++版本",本章介绍AVL树的Java实现版本,它的算法与C语言和C++版本一样.内容包括:1. AVL树的介绍 ...
- AVL树(一)之 图文解析 和 C语言的实现
概要 本章介绍AVL树.和前面介绍"二叉查找树"的流程一样,本章先对AVL树的理论知识进行简单介绍,然后给出C语言的实现.本篇实现的二叉查找树是C语言版的,后面章节再分别给出C++ ...
- AVL树之 Java的实现
AVL树的介绍 AVL树是高度平衡的而二叉树.它的特点是:AVL树中任何节点的两个子树的高度最大差别为1. 上面的两张图片,左边的是AVL树,它的任何节点的两个子树的高度差别都<=1:而右边的不 ...
随机推荐
- OpenCV 图像旋转实现
1 旋转矩形 首先建议阅读图像旋转算法原理-旋转矩阵,这篇博客可以让你很好地理解图像中的每一个点是如何进行旋转操作的.其中涉及到了图像原点与笛卡尔坐标原点之间的相互转换以及点旋转的一些公式推导. 这里 ...
- opencv2.4.10与VS2013的环境配置
前言 项目几乎都是图像相关的,一般都会用到opencv开源库,就涉及到windows下opencv的环境配置问题,本文对此进行介绍. 环境 系统环境:win10_x64(其他windows系统类似); ...
- css样式 float的理解
float w3cSchool里解释说, 浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止.由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样 ...
- test20181016 B君的第一题
题意 分析 考场爆零做法 考虑位数少的一定更小,高位小的一定更少. 然后计算一定位数下不同数字的个数,然后从高到低依次确定数位. 特例:如果确定的高位的后缀出现了x,那么要把x调整到后缀去,这样一定更 ...
- 用pthon来写个跳板机
用pthon来写个跳板机 1.需求 程序一:1.后台管理- 堡垒机上创建用户和密码(堡垒机root封装的类,UserProfile表)- .bashrc /usr/bin/python3 /dat ...
- signal信号
1.signal信号调试 http://hongjiang.info/shell-script-background-process-ignore-sigint/
- dbt 的知识文档管理
dbt 支持docs的管理,可以方便进行分享,以及大家的可视化工作 有一篇文档讲的特别好分析了知识共享,知识管理的重要性(dbt 对应公司的ceo) https://blog.fishtownanal ...
- 几本不错的graphql 电子书
当前专门讲graphql 的数据不是很多,但是越来越多的graphql 项目的出现以及graphql 自身的 便捷,老外已经有人去写graphql 的设计以及基本使用了. ebooks 地址 http ...
- sql server 数字字符串的排序
假如我们有这样的数据格式1#XXXXX 20#CCCCC等的一系列数据那么我们如何可以排序出1 ,2,3,4,5,6,7.......这样的数据呢 我们知道整数是可以排序成这样的格式的,但是字符串就不 ...
- zz 史上最全--各银行借记卡的年费、小额管理费、转账费等!
史上最全--各银行借记卡的年费.小额管理费.转账费等! 发布时间:2015-01-14 17:28:10 还在迷茫借记卡自费的菜主儿们~菜菜特别整理关于各银行借记卡.存折账户等的年费.小额管理费.转账 ...