# -*- 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. SQL死锁知识及解决办法

    [翻译]:SQL死锁-死锁排除 min.jiang 2014-03-18 00:23 阅读:874 评论:1     项目中死锁的解决经历 min.jiang 2014-03-17 01:09 阅读: ...

  2. 实习培训——Java基础(4)

    实习培训——Java基础(4) 1 多态 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作,多态性是对象多种表现形式的体现. 现实中,比如我们按下 ...

  3. PAT 1072 Gas Station[图论][难]

    1072 Gas Station (30)(30 分) A gas station has to be built at such a location that the minimum distan ...

  4. python输入与输出165

    s = 'Hello,Runoob' print(s) str(s) print(s) print(repr(s)) print(1/7) print(str(1/7)) print(repr(1/7 ...

  5. 使用gunicorn部署Flask项目

    [*] 本文出处:http://b1u3buf4.xyz/ [*] 本文作者:B1u3Buf4 [*] 本文授权:禁止转载 从自己的博客移动过来. gunicorn是一个python Wsgi的WEB ...

  6. jmeter 正则表达式提取器的使用(提取第一个匹配结果)

    原文地址https://www.cnblogs.com/xueli/p/7405258.html?utm_source=itdadao&utm_medium=referral 正则表达式的用处 ...

  7. Mysql查询一个表的所有字段名

    select COLUMN_NAME from information_schema.`COLUMNS`        -- 这行不变,照抄 where TABLE_SCHEMA = 'xerp'   ...

  8. distinct count

    实验:查询一个column的无重复记录,需要知道有多少条记录,并显示记录. 统计记录用count(*)函数,无重复记录distinct,以emp表为例. (1)先查询无重复记录 [@more@] SQ ...

  9. jms应用

    构建jms http://blog.csdn.net/haoxingfeng/article/details/9167895

  10. zw版【转发·台湾nvp系列Delphi例程】HALCON HomMat2dRotate1

    zw版[转发·台湾nvp系列Delphi例程]HALCON HomMat2dRotate1 procedure TForm1.Button1Click(Sender: TObject);var img ...