# -*- coding: utf-8 -*-
from enum import Enum #参考http://blog.csdn.net/niteip/article/details/11840691/
#参考https://www.cnblogs.com/suimeng/p/4560056.html
#todo 还没有考虑高度的增减,只考虑了平衡因子
#todo 加上非递归遍历二叉树 class BFStatus(Enum):
# 左子树的高度减去右子树的高度 RH,EH,LH分别表示右子树较高,左右子树等高,左子树较高
LH = 1
EH = 0
RH = -1 class TreeNode(object):
def __init__(self):
self.lson = None
self.rson = None
self.pnode = None
self.data = None
self.freq = 0
self.hgt = -1
self.bfstatus = BFStatus().EH class AVLTree(object):
def __init__(self,root_node):
self.root = TreeNode def height(self,node):
if node is not None:
return node.hgt
return -1 def max(self,campa,campb):
if campa > campb:
return campa
else:
return campb def single_rotate_right(self, node): # 右单旋转 RR
parent_node = node.pnode
node1 = node.lson
node.lson = node1.rson
node1.rson = node
if parent_node.lson == node:
parent_node.lson = node1
else:
parent_node.rson = node1
node1.pnode = parent_node
node.pnode = node1 def single_rotate_left(self, node): # 左单旋转 LL
parent_node = node.pnode
node1 = node.rson
node.rson = node1.lson
node1.lson = node
if parent_node.lson == node:
parent_node.lson = node1
else:
parent_node.rson = node1
node1.pnode = parent_node
node.pnode = node1 def LeftBalance(self,node):
lchild = node.lson
BFStatus_code = BFStatus()
if lchild.bfstatus == BFStatus_code.EH:
node.bfstatus = lchild.bfstatus = BFStatus_code.LH
lchild.bfstatus = BFStatus.RH
self.single_rotate_right(node)
elif lchild.bfstatus == BFStatus_code.LH:#LL型
node.bfstatus = lchild.bfstatus = BFStatus.EH
self.single_rotate_right(node)
elif lchild.bfstatus == BFStatus.RH:#LR型
rchild = lchild.rson
if rchild.bfstatus == BFStatus.EH:
node.bfstatus = BFStatus.RH
lchild.bfstatus = BFStatus.EH
elif rchild.bfstatus == BFStatus.LH:
node.bfstatus = BFStatus.EH
lchild.bfstatus = BFStatus.LH
elif rchild.bfstatus == BFStatus.RH:
node.bfstatus = BFStatus.EH
lchild.bfstatus = BFStatus.EH
rchild.bfstatus = BFStatus.EH
self.single_rotate_left(lchild)
self.single_rotate_right(node) def RightBalance(self,node):
rchild = node.rson
BFStatus_code = BFStatus()
if rchild.bfstatus == BFStatus_code.RH:
node.bfstatus = node.bfstatus = BFStatus_code.EH
self.single_rotate_left(node)
elif rchild.bfstatus == BFStatus_code.EH:#LL型
node.bfstatus = rchild.bfstatus = BFStatus.RH
rchild.bfstatus = BFStatus.LH
self.single_rotate_left(node)
elif rchild.bfstatus == BFStatus.LH:#LR型
lchild = rchild.lson
if lchild.bfstatus == BFStatus.LH:
node.bfstatus = BFStatus.EH
rchild.bfstatus = BFStatus.RH
elif lchild.bfstatus == BFStatus.RH:
node.bfstatus = BFStatus.LH
rchild.bfstatus = BFStatus.EH
elif lchild.bfstatus == BFStatus.EH:
node.bfstatus = BFStatus.EH
rchild.bfstatus = BFStatus.EH
lchild.bfstatus = BFStatus.EH
self.single_rotate_right(rchild)
self.single_rotate_left(node) def insertpri(self,node,data,stack_list,taller_param=True):
if node == None:
node = TreeNode()
node.data = data
node.pnode = stack_list[-1]
else:
stack_list.append(node)
if node.data < data:
(sign,taller) = self.insertpri(node.lson,data,stack_list)
if sign == False:
return (False,taller_param) if taller == True: if node.bfstatus == BFStatus().LH:
self.LeftBalance(node)
taller_param = False
elif node.bfstatus == BFStatus().EH:
node.bfstatus = BFStatus().LH
taller_param = True
elif node.bfstatus == BFStatus().RH:
node.bfstatus = BFStatus().EH
taller_param = False elif node.data > data:
stack_list.append(node)
if node.data < data:
(sign, taller) = self.insertpri(node.rson, data, stack_list)
if sign == False:
return (False, taller_param) if taller == True:
if node.bfstatus == BFStatus().LH:
node.bfstatus = BFStatus().EH
taller_param = False
elif node.bfstatus == BFStatus().EH:
node.bfstatus = BFStatus().RH
taller_param = True
elif node.bfstatus == BFStatus().RH:
self.RightBalance(node)
taller_param = False
else:
node.freq += 1 return (True,taller_param) def insert(self,data):
stack_list = []
self.insertpri(self.root,data,stack_list) def searchpri(self,node,data):
if node is None:
return None elif node.data > data:
self.searchpri(node.lson,data) elif node.data < data:
self.searchpri(node.rson,data) else:
return node def search(self,data):
self.searchpri(self.root,data) def go_far_left(self,node):
if node.lson is None:
return node
else:
self.go_far_left(node.lson) def go_far_right(self,node):
if node.rson is None:
return node
else:
self.go_far_right(node.rson) def delete_left(self,node,bfchild):
#当bf为-1或1变为0,或者孩子为空时说明子树高降低
if node.lson is None or (bfchild != BFStatus().EH and node.lson.bfstatus == BFStatus().EH):
#左子树树高降低
if node.bfstatus == BFStatus().EH:
node.bfstatus = BFStatus().RH
elif node.bfstatus == BFStatus().LH:
node.bfstatus = BFStatus().EH
elif node.bfstatus == BFStatus().RH:#原本右子树比较高
self.RightBalance(node) def delete_right(self,node,bfchild):
#当bf为LH或RH变为EH,或者孩子为空时说明子树高降低
if node.rson is None or (bfchild != BFStatus().EH and node.rson.bfstatus == BFStatus().EH):
#左子树树高降低
if node.bfstatus == BFStatus().EH:
node.bfstatus = BFStatus().LH
elif node.bfstatus == BFStatus().RH:
node.bfstatus = BFStatus().EH
elif node.bfstatus == BFStatus().LH:#原本左子树比较高
self.LeftBalance(node) def deletepri(self,node,data):
bfchild = BFStatus().EH
if node == None:
return None
if node.data > data:
bfchild = node.lson.bfstatus
node.lson = self.deletepri(node.lson,data)
self.delete_left(node,bfchild) elif node.data < data:
bfchild = node.rson.bfstatus
node.rson = self.deletepri(node.rson, data)
self.delete_left(node, bfchild) else:
if node.lson is not None: #不是叶子结点并且具有直接前驱
far_right_node = self.go_far_right(node.lson)#直接前驱
node.data = far_right_node.data
node.lson = self.deletepri(node.lson,far_right_node.data)#可以确定,删除的节点为当前节点的左子树的某一个节点
self.delete_left(node,bfchild)
elif node.rson is not None:
far_left_node = self.go_far_left(node.rson)
node.data = far_left_node.data
node.rson = self.deletepri(node.rson,far_left_node.data)
self.delete_right(node,bfchild)
else:#叶子结点
node = None return node def delete(self,data):
self.deletepri(self.root,data) def insubtree(self,node):
if node is None:
return
self.insubtree(node.lson)
print(node.data)
self.insubtree(node.rson) def traversal(self):
self.insubtree(self.root) if __name__ == '__main__':
root_node = TreeNode()
tree_obj = AVLTree(root_node)

  

Python实现自平衡二叉树AVL的更多相关文章

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

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

  2. 数据结构与算法--从平衡二叉树(AVL)到红黑树

    数据结构与算法--从平衡二叉树(AVL)到红黑树 上节学习了二叉查找树.算法的性能取决于树的形状,而树的形状取决于插入键的顺序.在最好的情况下,n个结点的树是完全平衡的,如下图"最好情况&q ...

  3. 二叉查找树(BST)、平衡二叉树(AVL树)(只有插入说明)

    二叉查找树(BST).平衡二叉树(AVL树)(只有插入说明) 二叉查找树(BST) 特殊的二叉树,又称为排序二叉树.二叉搜索树.二叉排序树. 二叉查找树实际上是数据域有序的二叉树,即对树上的每个结点, ...

  4. 平衡二叉树AVL - 插入节点后旋转方法分析

    平衡二叉树 AVL( 发明者为Adel'son-Vel'skii 和 Landis)是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1. 首先我们知道,当插入一个节点,从此插入点到树根 ...

  5. 二叉查找树、平衡二叉树(AVL)、B+树、联合索引

    1. [定义] 二叉排序树(二拆查找树)中,左子树都比节点小,右子树都比节点大,递归定义. [性能] 二叉排序树的性能取决于二叉树的层数 最好的情况是 O(logn),存在于完全二叉排序树情况下,其访 ...

  6. Java 树结构实际应用 四(平衡二叉树/AVL树)

    平衡二叉树(AVL 树) 1 看一个案例(说明二叉排序树可能的问题) 给你一个数列{1,2,3,4,5,6},要求创建一颗二叉排序树(BST), 并分析问题所在.  左边 BST 存在的问题分析: ...

  7. 【数据结构】平衡二叉树—AVL树

    (百度百科)在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增 ...

  8. 平衡二叉树AVL删除

    平衡二叉树的插入过程:http://www.cnblogs.com/hujunzheng/p/4665451.html 对于二叉平衡树的删除采用的是二叉排序树删除的思路: 假设被删结点是*p,其双亲是 ...

  9. 平衡二叉树AVL插入

    平衡二叉树(Balancedbinary tree)是由阿德尔森-维尔斯和兰迪斯(Adelson-Velskiiand Landis)于1962年首先提出的,所以又称为AVL树. 定义:平衡二叉树或为 ...

随机推荐

  1. 便于理解mysql内幕的各种逻辑图组

    便于理解mysql内幕的各种逻辑图组 http://blog.sina.com.cn/s/blog_445e807b0101ggtl.html 以下是个人一直以来从网络等各种途径收集到的一些对理解my ...

  2. Java-idea-eclipse-快捷键【mac,win】

    Mac键盘符号和修饰键说明 ⌘ Command ⇧ Shift ⌥ Option ⌃ Control ↩︎ Return/Enter ⌫ Delete ⌦ 向前删除键(Fn+Delete) ↑ 上箭头 ...

  3. inter x86 emulator accelerator(HAXM installer) not compatible with windows

    在SDK manager中遇到如下错误:这将导致AVD后期运行和启动方面的问题. 解决办法: 在如下的网址里面下载haxm-windows_v6_2_0这个文件的压缩包,自己手动安装即可.网站如下:点 ...

  4. jquery两稳定版本比较~~

    jquery历经了多个版本的更新,版本上的比较貌似没什么必要性,一般来说新的版本会比旧的版本各方面都略有提升,但由于新版中增加了各种新的功能,难免会引起bug的发生.评估一个版本是否适合当前开发场景使 ...

  5. GNS3的使用2

    IDE值没算好,巨卡.重新安装,重新算值.速度快了不少 IDE值:选出现次数多,并且数字大的 2960的选256M 另外加了2个模拟器:ASA防火墙.juniper路由器

  6. 菜刀php过waf

    关于PHP 一.waf为啥会拦截菜刀.菜刀在连接时,会向server端POST数据,抓包查看: 会看到他向server端post了 @eval(base64_decode($_POST[z0]));  ...

  7. 我的2015年ccf的解答

    只做了前三个题,在本地调试好了,不知为什么错了,好歹做了那么久,就记录一下了(注:这不是标准答案,只是我给出的解答) 这是第一题的代码: #include<stdio.h> #includ ...

  8. ajax response 系统错误时responseText出现一堆代码

    在后期维护webform的一个项目时遇到个比较大的坑,前台ajax请求,失败时弹出后台自定义的错误信息responsetext.结果在本地运行时能正常弹出“验证码错误”,而发布到服务器上respons ...

  9. 关于gg_bd_ad_720x90.js和follow.js

    很多人对gg_bd_ad_720x90.js和follow.js 抱有疑问,这是个什么鬼? 我也迷惑了一阵子,今天偶然发现了这两个源文件. 大家一起欣赏下. 注意红色加粗代码. 1.follow.js ...

  10. 《算法C语言实现》————快速-查找算法(quick-find algorithm)

    算法基础是一个整型数组,当且仅当第p个元素和第q个元素相等时,p和q时连通的.初始时,数组中的第i个元素的值为i,0<=i<N,为实现p与q的合并操作,我们遍历数组,把所有名为p的元素值改 ...