AVL树是一种特殊的二叉搜索树 (BST树),数据极端情况下, 二叉搜索树会退化成为单链表,但是AVL树通过旋转操作规避了这个问题。

查找平均复杂度:O(logn)

# AVL树不适于删除的情况
class AVLTreeNode(object):def __init__(self, data):self.data = data  # 数据self.left: AVLTreeNode = None  # 左子树self.right: AVLTreeNode = None  # 右子树self.height = 1  # 树高度def get_data(node: AVLTreeNode):return node.datadef set_data(node: AVLTreeNode, data):node.data = data# 获得树形结构
def get_left_node(node: AVLTreeNode):return node.leftdef get_right_node(node: AVLTreeNode):return node.rightdef get_height(node: AVLTreeNode):if node is None:return 0return node.heightdef get_max_node(node: AVLTreeNode):temp_node = nodeif temp_node.right is not None:return get_max_node(temp_node.right)else:return temp_nodedef get_min_node(node: AVLTreeNode):temp_node = nodeif temp_node.left is not None:return get_min_node(temp_node.left)else:return temp_nodedef get_node(node: AVLTreeNode, data):temp_node: AVLTreeNode = nodewhile temp_node:if data < temp_node.data:temp_node = temp_node.leftelif data > temp_node.data:temp_node = temp_node.rightelse:return temp_nodereturn None# 右旋:先记录待旋转节点的左节点,然后将左节点的right指向待旋转节点即可
def right_rotate(node: AVLTreeNode):head_node: AVLTreeNode = node.leftnode.left = head_node.right  # 将父节点的右侧放在待旋转节点的左侧head_node.right = node  # 将父节点的右指针指向待旋转节点node.height = max(get_height(node.left), get_height(node.right)) + 1head_node.height = max(get_height(head_node.left), get_height(head_node.right)) + 1return head_nodedef left_rotate(node: AVLTreeNode):head_node: AVLTreeNode = node.rightnode.right = head_node.lefthead_node.left = nodenode.height = max(get_height(node.left), get_height(node.right)) + 1head_node.height = max(get_height(head_node.left), get_height(head_node.right)) + 1return head_node# 先左旋,再右旋
def left_right_rotate(node: AVLTreeNode):son_node = left_rotate(node.left)node.left = son_nodereturn right_rotate(node)def right_left_rotate(node: AVLTreeNode):son_node = right_rotate(node.right)node.right = son_nodereturn left_rotate(node)# 左子树与右子树差距最大为1,否则及时调整
def adjust_height(node: AVLTreeNode):if get_height(node.right) - get_height(node.left) > 1:if get_height(node.right.right) > get_height(node.right.left):node = left_rotate(node)else:node = right_left_rotate(node)elif get_height(node.left) - get_height(node.right) > 1:if get_height(node.left.left) > get_height(node.left.right):node = right_rotate(node)else:node = left_right_rotate(node)else:passreturn nodedef insert_node(node: AVLTreeNode, data):if node is None:return AVLTreeNode(data)if (node.data is not None) and (data < node.data):  # 向左插入node.left = insert_node(node.left, data)node.height = max(get_height(node.left), get_height(node.right)) + 1node = adjust_height(node)elif (node.data is not None) and (data > node.data):  # 向右插入node.right = insert_node(node.right, data)node.height = max(get_height(node.left), get_height(node.right)) + 1node = adjust_height(node)else:print('Can not insert same value')return nodedef delete_node(node: AVLTreeNode, data):if node is None:return Noneif (node is not None) and (data < node.data):  # 左侧查询node.left = delete_node(node.left, data)node = adjust_height(node)elif (node is not None) and (data > node.data):  # 右侧查询node.right = delete_node(node.right, data)node = adjust_height(node)else:  # 在这里删除if (node.left is not None) and (node.right is not None):  # 左右节点都不为空node.data = get_min_node(node.right).datanode.right = delete_node(node.right, node.data)elif node.left is not None:  # 左节点不为空,右节点为空node = node.leftelse:  # 左节点为空,右节点未知node = node.rightif node is not None:node.height = max(get_height(node.left), get_height(node.right)) + 1adjust_height(node)return nodedef get_all(node: AVLTreeNode):values = []def add_values(values, node: AVLTreeNode):if node is not None:values = add_values(values, node.left)values.append(node.data)values = add_values(values, node.right)return valuesreturn add_values(values, node)def main():root = AVLTreeNode(10)number_list = (3, 2, 1, 4, 5, 6, 7, 15, 26, 17)for number in number_list:root = insert_node(root, number)all_values = get_all(root)del_note = delete_node(root, 3)all_values = get_all(root)passif __name__ == '__main__':main()

平衡二叉树(AVL)python实现相关推荐

  1. Python数据结构11:树的实现,树的应用,前中后序遍历,二叉查找树BST,平衡二叉树AVL树,哈夫曼树和哈夫曼编码

    1.概念 树一种基本的"非线性"数据结构. 相关术语: 节点Node:组成树的基本部分.每个节点具有名称,或"键值",节点还可以保存额外数据项,数据项根据不同的 ...

  2. [转]C#与数据结构--树论--平衡二叉树(AVL Tree)

    C#与数据结构--树论--平衡二叉树(AVL Tree) http://www.cnblogs.com/abatei/archive/2008/11/17/1335031.html 介绍 我们知道在二 ...

  3. 平衡二叉树AVL详解

    一.平衡二叉树的定义 平衡二叉树(Balanced Binary Tree)又被称为AVL树,它且具有以下性质: (1)它是一棵空树或它的左右两个子树的高度差的绝对值不超过1: (2)并且左右两个子树 ...

  4. 平衡二叉树平衡因子怎么计算_数据结构PHP 平衡二叉树(AVL)的平衡原理

    这篇文章主要介绍一下 平衡二叉树(AVL),对于 二分搜索树 来说,如果树上的 元素 是顺序 添加的,会导致数据退化成一个 链表,这样就会造成很严重的性能问题,此时就需要在 二分搜索树 的基础上,保证 ...

  5. [ 数据结构 ] 平衡二叉树(AVL)--------左旋、右旋、双旋

    0 引出 数列{1,2,3,4,5,6},要求创建一颗二叉排序树(BST), 并分析问题所在 回顾:二叉搜索树 左子树全部为空,从形式上看,更像一个单链表. 插入速度没有影响 查询速度明显降低(因为需 ...

  6. Java数据结构——平衡二叉树(AVL树)

    AVL树的引入 搜索二叉树有着极高的搜索效率,但是搜索二叉树会出现以下极端情况: 这样的二叉树搜索效率甚至比链表还低.在搜索二叉树基础上出现的平衡二叉树(AVL树)就解决了这样的问题.当平衡二叉树(A ...

  7. java 二叉树特点_java学习笔记-二叉树、平衡二叉树(AVL)、红黑二叉树(十)

    各种树 标签:数据结构范畴 二叉树的定义: 二叉树是树形结构的一个重要类型. 许多实际问题抽象出来的数据结构往往是二叉树的形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为 ...

  8. 二叉树(BT)、二叉查找树(BST)、平衡二叉树(AVL)、B-Tree、B+Tree、红黑树(BRT)

    目录 树的概念 树的分类 二叉树 二叉查找树 平衡二叉树(AVL) B-Tree(平衡多路查找树) B树的关键特征 B+Tree B+树关键特征 红黑树(BRT) 左旋 右旋 时间复杂度 树形结构是一 ...

  9. 平衡二叉树,AVL树之图解篇

    学习过了二叉查找树,想必大家有遇到一个问题.例如,将一个数组{1,2,3,4}依次插入树的时候,形成了图1的情况.有建立树与没建立树对于数据的增删查改已经没有了任何帮助,反而增添了维护的成本.而只有建 ...

  10. [树结构]平衡二叉树AVL

    平衡二叉树是一种二叉排序树,其中每一个节点的左子树和右子树的高度至多等于1,平衡二叉树又称为AVL树. 将二叉树节点的左子树深度减去右子树深度的值称为平衡因子BF,平衡二叉树上所有节点的平衡因子只可能 ...

最新文章

  1. Ubuntu 系统 Pycharm中无法使用中文输入法问题
  2. 听歌识曲原理探究以及样例代码
  3. 实验数据:将甲醛和亚硝酸的模拟分子网络分别计算100次的结果
  4. K8S水平伸缩器 - 自动伸缩微服务实例数量
  5. 复习Java异常处理_异常分类_自定义异常_线程初步了解
  6. 二、前端pink老师的CSS定位学习笔记(超详细,简单易懂)
  7. mysql分页概念_MySQL学习笔记之数据定义表约束,分页方法总结
  8. object转class_从零并发框架(三)异步转同步注解+字节码增强代理实现
  9. Numpy Mathematical functions 数学函数
  10. java等边三角形代码_Java实现等边三角形--小程序,大思想
  11. 微信分身版电脑版_电脑版营销wetool电脑版-网站
  12. editplus怎么在前后插入字符
  13. appium连接真机时,报错:error: device unauthorized.
  14. 小白Linux入门之:常用命令介绍
  15. golang 使用 goquery 抓取 知乎周刊
  16. 【绝知此事要躬行】线性表之链表OJ(上)
  17. 有监督学习、无监督学习、半监督学习、强化学习
  18. portknocking(端口试探) demo
  19. 业务智能化成为电信运营业的总体发展趋势
  20. Linux线程数和系统线程数查看

热门文章

  1. MySQL 获取首次登录日期、登录设备号
  2. 负margin应用案例几则(转载+总结)
  3. 高性能Web服务器Nginx使用指南
  4. android onSaveInstance方法项目中的实践
  5. 明小子动力上传拿webshell(1).zip
  6. IOS 代码控制控件始终居中
  7. 百度BAE JAVA环境项目部署和调试
  8. 远东传动收购机器人_一张图为你总结最近5年在机器人领域收购案例
  9. python3 socketserver源码解析_解读python中SocketServer源码
  10. python怎么批量处理数据_python如何批量处理excel数据?_后端开发