欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > 数据结构编程实践20讲(Python版)—07AVL树

数据结构编程实践20讲(Python版)—07AVL树

2024/11/30 10:41:08 来源:https://blog.csdn.net/qq_32882309/article/details/142765167  浏览:    关键词:数据结构编程实践20讲(Python版)—07AVL树

本文目录

    • 07 AVL树(Adelson-Velsky and Landis Tree)
      • S1 说明
      • S2 示例
      • S3 问题:简单的联系人管理系统
        • Python3程序
        • 代码说明
      • S4 问题:用AVL树实现优先队列
        • Python3程序
        • 代码说明
      • S5 问题:使用AVL树实现符号表
        • Python3程序
        • 代码说明

往期链接

01 数组02 链表03 栈04 队列05 二叉树06 二叉搜索树

07 AVL树(Adelson-Velsky and Landis Tree)

S1 说明

AVL树(Adelson-Velsky and Landis Tree)是一种自平衡的二叉搜索树,它通过维护每个节点的平衡因子来确保树的高度尽可能低,从而保证查找、插入和删除操作的时间复杂度为 O(log n)。
特征

(1)平衡因子

AVL树中的每个节点都有一个平衡因子(Balance Factor),定义为该节点的左子树高度减去右子树高度。平衡因子可以为 -1、0 或 1:

  • 0:表示左右子树高度相等。
  • 1:表示左子树比右子树高 1。
  • -1:表示右子树比左子树高 1。
    如果某个节点的平衡因子的绝对值大于 1,则该节点不平衡,需要进行旋转操作来恢复平衡。

(2)旋转操作

为了保持树的平衡,AVL树使用四种基本的旋转操作:

  • 右旋转(Right Rotation):用于处理左左情况(LL)。
  • 左旋转(Left Rotation):用于处理右右情况(RR)。
  • 左-右旋转(Left-Right Rotation):用于处理左右情况(LR),先左旋再右旋。
  • 右-左旋转(Right-Left Rotation):用于处理右左情况(RL),先右旋再左旋。

(3)高度平衡

AVL树的高度在最坏情况下为 O(log n),这意味着每次插入或删除操作后,树的高度不会超过 log(n),从而保证有效的查找性能。

(4)查找性能

查找操作的时间复杂度为 O(log n),与普通的二叉搜索树相比,AVL树由于其自平衡特性,可以提供更快的查找速度,尤其是在频繁插入和删除的情况下。

(5)插入和删除

在插入和删除节点时,AVL树会根据节点的平衡因子自动调整树的结构,可能需要多次旋转以保证整个树的平衡。

S2 示例

import matplotlib.pyplot as plt# macos系统显示中文
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']class Node:def __init__(self, key):self.key = key  # 节点的键值self.left = None  # 左子节点self.right = None  # 右子节点self.height = 1  # 节点的高度class AVLTree:def __init__(self):self.root = None  # 初始化根节点为 Nonedef height(self, node):if not node:return 0  # 如果节点为空,高度为 0return node.height  # 返回节点的高度def balance(self, node):if not node:return 0  # 如果节点为空,平衡因子为 0return self.height(node.left) - self.height(node.right)  # 计算平衡因子def update_height(self, node):if not node:return# 更新节点高度为左右子树高度的最大值加一node.height = 1 + max(self.height(node.left), self.height(node.right))def right_rotate(self, y):x = y.left  # 获取当前节点的左子节点T2 = x.right  # 获取左子节点的右子节点# 执行右旋操作x.right = y  # 左子节点成为新的根节点y.left = T2  # 原根节点的左子节点指向 T2# 更新节点高度self.update_height(y)self.update_height(x)return x  # 返回新的根节点def left_rotate(self, x):y = x.right  # 获取当前节点的右子节点T2 = y.left  # 获取右子节点的左子节点# 执行左旋操作y.left = x  # 右子节点成为新的根节点x.right = T2  # 原根节点的右子节点指向 T2# 更新节点高度self.update_height(x)self.update_height(y)return y  # 返回新的根节点def insert(self, root, key):if not root:return Node(key)  # 如果当前节点为空,插入新节点# 根据键值插入节点if key < root.key:root.left = self.insert(root.left, key)  # 插入左子树else:root.right = self.insert(root.right, key)  # 插入右子树# 更新当前节点的高度self.update_height(root)# 计算当前节点的平衡因子balance = self.balance(root)# 左左情况(LL)if balance > 1 and key < root.left.key:return self.right_rotate(root)# 右右情况(RR)if balance < -1 and key > root.right.key:return self.left_rotate(root)# 左右情况(LR)if balance > 1 and key > root.left.key:root.left = self.left_rotate(root.left)  # 先左旋return self.right_rotate(root)  # 再右旋# 右左情况(RL)if balance < -1 and key < root.right.key:root.right = self.right_rotate(root.right)  # 先右旋return self.left_rotate(root)  # 再左旋return root  # 返回当前节点def insert_key(self, key):self.root = self.insert(self.

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com