首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在O(log(n))中平衡这棵AVL树?

要在O(log(n))时间复杂度内平衡一棵AVL树,首先需要理解AVL树的基本概念和平衡机制。

基础概念

AVL树是一种自平衡二叉搜索树,其每个节点都包含一个平衡因子(即左子树高度减去右子树高度),并且所有节点的平衡因子的绝对值不超过1。

平衡机制

当插入或删除节点时,可能会破坏树的平衡。为了恢复平衡,需要进行旋转操作。旋转操作分为四种类型:

  1. 左旋(Left Rotation)
  2. 右旋(Right Rotation)
  3. 左右旋(Left-Right Rotation)
  4. 右左旋(Right-Left Rotation)

插入操作

  1. 插入节点:按照二叉搜索树的规则插入新节点。
  2. 更新平衡因子:从插入点向上回溯,更新每个祖先节点的平衡因子。
  3. 检查平衡:如果在更新过程中发现某个节点的平衡因子绝对值超过1,则需要进行旋转操作。

删除操作

  1. 删除节点:按照二叉搜索树的规则删除节点。
  2. 更新平衡因子:从删除点向上回溯,更新每个祖先节点的平衡因子。
  3. 检查平衡:如果在更新过程中发现某个节点的平衡因子绝对值超过1,则需要进行旋转操作。

示例代码

以下是一个简单的Python示例,展示如何在插入节点后进行平衡:

代码语言:txt
复制
class TreeNode:
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None
        self.height = 1

class AVLTree:
    def getHeight(self, node):
        if not node:
            return 0
        return node.height

    def getBalance(self, node):
        if not node:
            return 0
        return self.getHeight(node.left) - self.getHeight(node.right)

    def leftRotate(self, z):
        y = z.right
        T2 = y.left

        y.left = z
        z.right = T2

        z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right))
        y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right))

        return y

    def rightRotate(self, z):
        y = z.left
        T3 = y.right

        y.right = z
        z.left = T3

        z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right))
        y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right))

        return y

    def insert(self, root, key):
        if not root:
            return TreeNode(key)
        elif key < root.key:
            root.left = self.insert(root.left, key)
        else:
            root.right = self.insert(root.right, key)

        root.height = 1 + max(self.getHeight(root.left), self.getHeight(root.right))

        balance = self.getBalance(root)

        # Left Left Case
        if balance > 1 and key < root.left.key:
            return self.rightRotate(root)

        # Right Right Case
        if balance < -1 and key > root.right.key:
            return self.leftRotate(root)

        # Left Right Case
        if balance > 1 and key > root.left.key:
            root.left = self.leftRotate(root.left)
            return self.rightRotate(root)

        # Right Left Case
        if balance < -1 and key < root.right.key:
            root.right = self.rightRotate(root.right)
            return self.leftRotate(root)

        return root

应用场景

AVL树广泛应用于需要高效查找、插入和删除操作的场景,例如数据库索引、文件系统等。

参考链接

通过上述方法,可以在O(log(n))时间复杂度内平衡AVL树,确保树的高度始终保持在O(log(n)),从而保证各种操作的高效性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

在平衡中追寻高度:探秘AVL树的自我调节之美

前言 继上篇C++探索之旅:打造高效二叉搜索树的奥秘与实践,我们继续探讨二叉搜索树的PLUS版——AVL树 在数据结构的世界里,树木生长的过程并非一帆风顺。如何在高度与平衡间取得微妙的和谐?...AVL树的查找、插入和删除在平均和最坏情况下的时间复杂度都是O(log n)。...如果它有 n 个结点,其高度可保持在 O ( log2n ),搜索时间复杂度为 O(log2n )。...无论是这四种旋转中的哪一个,都要保证以下两点:首先在旋转的过程中要保证这棵树是搜索树,其次经过旋转后,这棵树应该变成平衡树,且降低这个子树的高度。...六、AVL 树的性能 AVL 树是一颗绝对平衡的二叉搜索树,其要求每个结点的左右子树高度差的绝对值都不超过1,这样在查询时可以保证高效的时间复杂度,即O(log2n)。

8810

文心一言 VS 讯飞星火 VS chatgpt (160)-- 算法导论12.4 2题

一棵有 n个结点的二叉搜索树中结点的平均深度为 O(lgn),给出这棵树高度的一个渐近上界。...这并不意味着树的高度也是 O(log n),因为可能存在一些非常深的节点。 对于二叉搜索树来说,如果它是平衡的,即对于任何节点,其左右子树的高度差不超过 1,那么树的高度就是 O(log n)。...为了解决这个问题,我们可以使用自平衡二叉搜索树(如 AVL 树或红黑树),它们保证了树的高度始终为 O(log n),即使在插入或删除节点导致树不平衡时也能通过旋转操作恢复平衡。...根据二叉搜索树的性质,对于包含 n 个节点的完美平衡二叉搜索树,其高度 h 是 log2(n+1)(这是因为完美平衡的二叉树中,每个节点的左右子树大小都相差不超过1,这样可以使得树的高度最小)。...首先,创建一个平衡的二叉搜索树,例如 AVL 树或红黑树。这些树在插入和删除操作后会自动调整,以保持树的高度接近 O(logn)。在这种情况下,树中节点的平均深度接近 O(logn)。 2.

13020
  • 文心一言 VS 讯飞星火 VS chatgpt (160)-- 算法导论12.4 2题

    一棵有 n个结点的二叉搜索树中结点的平均深度为 O(lgn),给出这棵树高度的一个渐近上界。...这并不意味着树的高度也是 O(log n),因为可能存在一些非常深的节点。 对于二叉搜索树来说,如果它是平衡的,即对于任何节点,其左右子树的高度差不超过 1,那么树的高度就是 O(log n)。...为了解决这个问题,我们可以使用自平衡二叉搜索树(如 AVL 树或红黑树),它们保证了树的高度始终为 O(log n),即使在插入或删除节点导致树不平衡时也能通过旋转操作恢复平衡。...根据二叉搜索树的性质,对于包含 n 个节点的完美平衡二叉搜索树,其高度 h 是 log2(n+1)(这是因为完美平衡的二叉树中,每个节点的左右子树大小都相差不超过1,这样可以使得树的高度最小)。...首先,创建一个平衡的二叉搜索树,例如 AVL 树或红黑树。这些树在插入和删除操作后会自动调整,以保持树的高度接近 O(logn)。在这种情况下,树中节点的平均深度接近 O(logn)。 2.

    14620

    AVL树实现

    ⽐ 如⼀棵树是2个结点,4个结点等情况下,⾼度差最好就是1,⽆法作为⾼度差是0 AVL树整体结点数量和分布和完全⼆叉树类似,⾼度可以控制在 logN,那么增删查改的效率也可 以控制在O(logN) ,相...说明:下⾯的图中,有些结点我们给的是具体值,如10和5等结点,这⾥是为了⽅便讲解,实际中是什么值都可以,只要⼤⼩关系符合搜索树的规则即可。...旋转核⼼步骤,因为5 树的值 树,10变成5的右⼦树,5变成这棵树新 的根,符合搜索树的规则,控制了平衡,同时这棵的⾼度恢复到了插⼊之前的h+2,符合旋转原 则。...这棵树 这棵树就平衡了。...结束语: AVL树是一种平衡二叉搜索树,通过旋转操作确保树的高度始终保持平衡,从而保证插入、删除和查找操作的时间复杂度始终为 ( O(\log n) )。

    8310

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

    前言 上一篇文章讨论的二叉搜索树,其时间复杂度最好的情况下是O(log(n)),但是最坏的情况是O(n),什么时候是O(n)呢? 像这样: ?...’skii和Landis 满足高度平衡属性的二叉树就是AVL树 高度平衡属性是:对于树中的每一个位置p,p的孩子的高度最多相差1 很显然前言中的第一个图并不满足高度平衡属性,第二个是满足的。...同时高度平衡属性也意味着一颗AVL树的子树同样是AVL树 并且可以通过证明(这里就不再证了)得到AVL树的高度是O(log n) 所以得出结论,AVL树可以使时间复杂度保持O(log n) 接下来的问题就是怎样保持二叉树的高度平衡属性...第一次相当于对5、10、15、17这棵子树进行了一次RR旋转,旋转方式与之前的RR方式相同,就像是以15为中心向左旋转,旋转的结果使得整棵树变成了LL的不平衡形态,然后再按照LL的旋转方式对整棵树处理。...RL同样是LR的相反模式,先将22、25、30、40这棵子树进行LL旋转,再将整棵树进行RR旋转 理解了avl保持平衡从方式后,就可以用代码来实现了 Python实现 我们使用AVL对上一篇文章中的有序映射进行优化

    61320

    Java 中 HashMap 数据结构分析(语言无关)

    二叉搜索树的特性便于我们进行查找插入删除等一系列操作,其时间复杂度为O(logn),但是,如果遇见最差的情况,比如以下这棵树: ?...这棵树,说是树,其实它已经退化成链表了,但从概念上来看,它仍是一棵二叉搜索树,只要我们按照逐次增大,如1、2、3、4、5、6的顺序构造一棵二叉搜索树,则形如上图。...那么插入的时间复杂度就变成了O(n),导致这种糟糕的情况原因是因为这棵树极其不平衡,右树的重量远大于左树,因此我们提出了叫平衡二叉搜索树的结构,又称之为 AVL 树,是因为平衡二叉搜索树的发明者为 Adel...数组中如果找到某个值在什么位置,需要循环遍历整个数组,时间复杂度为O(n),而Hash表的时间复杂度基本为O(1)。因为哈希通过一次计算大幅度缩小查找范围,比从全部数据里查找速度要快。...当 HashMap 中有大量的元素都存放到同一个桶(即数组的一个元素)中时,这个桶下有一条长长的链表,这个时候 HashMap 就相当于一个单链表,假如单链表有 n 个元素,遍历的时间复杂度就是 O(n

    70220

    【高阶数据结构】AVL树详解

    这几个容器有个共同点是:其底层都是按照二叉搜索树来实现的,但是二叉搜索树有其自身的缺陷,假如往树中插入的元素有序或者接近有序,二叉搜索树就会退化成单支树,时间复杂度会退化成O(N),因此map、set等关联式容器的底层结构是对二叉树进行了平衡处理...如果它有n个结点,其高度可保持在 O(log_2 n) ,搜索的时间复杂度O( log_2 n) 。 2....那大家想一下:我们在AVL树中插入了一个新结点之后,会不会影响到树中结点的平衡因子? 毋庸置疑,这当然是会的!...AVL树的旋转 如果在一棵原本是平衡的AVL树中插入一个新节点,可能造成不平衡,此时必须调整树的结构,使之平衡化。...AVL树的性能 AVL树是一棵绝对平衡的二叉搜索树,其要求每个节点的左右子树高度差的绝对值都不超过1,这样可以保证查询时高效的时间复杂度,即 log_2 (N) 。

    1.5K10

    数据结构之AVL平衡二叉树

    因为这个特性,当对二叉搜索树进行中序遍历的时候,输出一定是按升序排列的。 利用二叉搜索树,可以在O(log N)的时间复杂度下查找指定元素。...然而如果在插入二叉搜索树的时候,是以升序的方式,比如[1,2,3,4,5],二叉搜索树会一直往右节点增加,这样会导致二叉搜索树退化成链表,查找的时间复杂度也降到了O(N)。...所谓平衡,就是让树的左右子节点的高度尽量相等,左右两边尽量保持平衡,使节点平均分布在两侧,这样使得查找效率始终维持在O(log N),也就是树的高度。...百度百科:在计算机科学中,AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。...O(log N) 。

    58820

    JS数据结构之AVL树

    介绍 AVL树(Adelson-Velsky and Landis Tree)是最早被发明的自平衡二叉查找树,它能保证查找、插入和删除在平均和最坏情况下的时间复杂度都是O(log n)。...Balance Factor,平衡因子,是当前节点的左子树高度减去右子树高度。 当平衡因子处于[-1, 1]区间时,我们认为这棵树是平衡的,否则就是不平衡状态,需要通过一次或多次旋转使其重新平衡。...左单旋转 当node.left.left被进行了一次插入操作,导致这棵树不平衡时,需要进行左单旋转,过程如下: 分析: 由于插入了节点x,使得原本以k1为根节点的AVL树不再平衡。...,需要进行左双旋转,过程如下 分析: 由于插入了节点x,使得原以k3为根节点的AVL树不再平衡。...这里不可能两个子树一样高,因为刚打破平衡时这棵树就要被重新调整了。

    70510

    平衡搜索二叉树之AVL树解析

    中序访问有序 1.2、平衡二叉树 在二叉树中,由于每个节点的左右子树可以存在空树,所以在节点数一定的情况下,如果树中的空节点越多,树的高度就会越高,如果我们看最坏的情况,这棵树将退化为一条单链。...特别的: 在结合以上2点后,这棵树由于: ①中序遍历有序 ②遍历时可根据大小快速访问到对应节点(每一层节点数量都是指数增加) 一棵被用于搜索的理想二叉树就横空出世了,即平衡搜索二叉树。...二、AVL树 2.1AVL树的概念 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查 找元素相当于在顺序表中搜索元素,效率低下。...如果它有n个结点,其高度可保持在 O(log_2 n),搜索时间复杂度O(log_2 n)。...先按照二叉搜索树的规则将节点插入到AVL树中 // // 2.

    48740

    数据结构之AVL树的 “奥秘“

    二叉树查询性能分析: 插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能 对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索在二叉搜索树树平均查找长度是结点的深度的函数...AVL树的概念: 1. 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺 序表中搜索元素,效率低下。...这个我们要定义一个平衡因子,平衡因子 = 右树高度 - 左树高度。 3. 如果一棵二叉搜索树是高度平衡的,它就是AVL树。...如果它有n个结点,其高度可保持在 搜索时间复杂 度(Log2^N)。 二 AVL树的实现: 1....* 因为要验证的这棵树的平衡因子,是我们自己定义的,防止出错。

    11710

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

    平衡二叉树 世界需要平衡,破坏平衡的一方,也许会一时很强势的称霸,最终的结局逃不过孤立和落空 定义 左、右子树是平衡二叉树; 所有结点的左、右子树深度之差的绝对值≤ 1平衡因子:该结点左子树与右子树的高度差...任一结点的平衡因子只能取:-1、0 或 1;如果树中任意一个结点的平衡因子的绝对值大于1,则这棵二叉树就失去平衡,不再是AVL树; 对于一棵有n个结点的AVL树,其高度保持在O(log2n)数量级,ASL...也保持在O(log2n)量级。...在二叉平衡树上进行查找时, 查找过程中和给定值进行比较的关键字的个数和 log(n) 相当。...变种的AVL树——红黑树 颜色特征:每个结点为“黑色”或“红色” 根特征:根结点永远是“黑色”的 外部特征:扩充外部叶结点都是空的“黑色”结点 内部特征:“红色”结点的两个子结点都是“黑色”的,即:不允许两个连续的红色结点

    561105

    【C++】AVL树

    ⽐如⼀棵树是2个结点,4个结点等情况下,⾼度差最好就是1,⽆法作为⾼度差是0 AVL树整体结点数量和分布和完全⼆叉树类似,⾼度可以控制在 ,那么增删查改的效率也可 以控制在 ,相⽐⼆叉搜索树有了本质的提升...说明:下⾯的图中,有些结点我们给的是具体值,如10和5等结点,这⾥是为了⽅便讲解,实际中是什么值都可以,只要⼤⼩关系符合搜索树的规则即可。...• 旋转核⼼步骤,因为5 树的值 树,10变成5的右⼦树,5变成这棵树新的根,符合搜索树的规则,控制了平衡,同时这棵的⾼度恢复到了插⼊之前的h+2,符合旋转原...• 旋转核⼼步骤,因为10 树的值 树,10变成15的左⼦树,15变成这棵 树新的根,符合搜索树的规则,控制了平衡,同时这棵的⾼度恢复到了插⼊之前的h+2,符合旋转原则...右单旋解决的纯粹的左边⾼,但是插⼊在b⼦树中,10为跟的⼦树不再是单纯的左边⾼,对于10是左边⾼,但是对于5是右边⾼,需要⽤两次旋转才能解决,以5为旋转点进⾏⼀个左单旋,以10为旋转点进⾏⼀个右单旋,这棵树这棵树就平衡了

    10110

    【C++学习篇】AVL树

    =》⽐如⼀棵树是2个结点,4个结点等情况下,⾼度差最好就是1,⽆法作为⾼度差是0 AVL树整体结点数量和分布和完全⼆叉树类似,⾼度可以控制在 logN ,那么增删查改的效率也可以控制在 O(logN...旋转核⼼步骤,因为5 树的值 树,10变成5的右⼦树,5变成这棵树新的根,符合搜索树的规则,控制了平衡,同时这棵的⾼度恢复到了插⼊之前的h+2,符合旋转原 则。...旋转核⼼步骤,因为10 树的值 树,10变成15的左⼦树,15变成这棵树新的根,符合搜索树的规则,控制了平衡,同时这棵的⾼度恢复到了插⼊之前的h+2,符合旋转原则。...右单旋解决的纯粹的左边⾼,但是插⼊在b⼦树中,10为跟的⼦树不再是单纯的左边⾼,对于10是左边⾼,但是对于5是右边⾼,需要⽤两次旋转才能解决,以5为旋转点进⾏⼀个左单旋,以10为旋转点进⾏⼀个右单旋,这棵树这棵树就平衡了...图7和图8分别为左右双旋中h==0和h==1具体场景分析,下⾯我们将a/b/c⼦树抽象为⾼度h的AVL⼦树进⾏分析,另外我们需要把b⼦树的细节进⼀步展开为8和左⼦树⾼度为h-1的e和f⼦树,因为 我们要对

    8910

    【动态图文详解,史上最易懂的红黑树讲解】手写红黑树(Red Black Tree)

    红黑树:一棵自平衡(AVL)+二叉查找树(BST) 什么是红黑树 红黑树,Red-Black Tree 「RBT」是一个自平衡(不是绝对的平衡)的二叉查找树(BST)。...红黑树是一种特化的AVL树(平衡二叉树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。 ?...它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。...(保证这棵树尽量是平衡的。) 性质1:每个节点要么是黑色,要么是红色。 ? 性质2:根节点是黑色。 ? 性质3:每个叶子节点(NIL)是黑色。 性质4:每个红色结点的两个子结点一定都是黑色。...但由于只需要保证RBT基本平衡就可以了。因此插入结点最多只需要2次旋转,这一点和AVL的插入操作一样。虽然变色操作需要O(logN),但是变色操作十分简单,代价很小。

    18.9K31

    AVL树

    因此,他是带有条件的搜索二叉树。这个条件保证了AVL树的深度是O(log n).最简单的想法是左右两棵子树保持相同的高度。但是这种条件过于苛刻,难以使用。AVL只要求深度之差不超过1。...AVL解决了二叉搜索树带来的不平衡问题。但是要求变成了我们必须在每次操作后进行调整,以使得AVL树保持平衡。...在AVL树中就不一一实现了,只就插入做了实现,我对删除采用的是懒惰删除法。在此不在说明。只测试一下AVL树的深度是不是O(log n)以及中序遍历输出是不是有序的。...{ T = RLRotate(T); //插入右子树的左子树 } } } else { //x在这棵AVL树中,我们什么都不做,当然,我们也可以重新设计AVL...//这样的做法为我们在AVL树中做一个删除也提供了一种方式,即:懒惰删除。 //我们并不将这个节点从树中删除,而只是去更改数据出现的次数减1。

    46420

    第15期:索引设计(索引组织方式 B+ 树)

    数据库系统和文件系统一般都采用 B+ 树来存储索引信息,B+ 树兼顾写和读的性能,最极端时检索复杂度为 O(logN),其中 N 指的是节点数量,logN 表示对磁盘 IO 扫描的总次数。...比如节点 10 的平衡因子就是 3; 图 1 是一颗非常普通的树,非常容易退化为一张链表。如果把图 1 换成如下图, 根节点就变为 4,6 退化为 4 的儿子节点,这棵树就退化为一张链表。...链表的查找非常慢,只能按照节点顺序查找,每个节点都遍历一遍,时间复杂度为 O(n),无法随机查找。...每个节点的平衡因子差值绝对值 <=1; 4. 每个节点都符合以上三个特征。 满足这样条件的树叫平衡二叉树(AVL)树。 问:那再次查找节点 5,需要遍历多少次呢?...也就说 AVL 树在查找方面性能很好,最坏的情况是找到一个节点需要消耗的次数也就是树的层数, 复杂度为 O(logN) 如果节点非常多呢?

    33610

    红黑树的平衡之舞:数据结构中的优雅艺术

    时间复杂度: 查找:O(log n) 插入:O(log n) 删除:O(log n) 自平衡:在插入和删除操作后,红黑树通过旋转和重新着色来保持上述性质,从而确保树的高度尽量低。...红黑树:相对宽松的平衡条件,通过颜色属性和旋转操作维护平衡。虽然高度比AVL树大,但仍然保持在O(log n)的范围内。...6.2 查找操作 AVL树:查找操作效率更高,时间复杂度为O(log n),因为树的高度较小。 红黑树:查找操作的时间复杂度同样为O(log n),但由于可能较高的树高度,平均查找速度稍慢。...6.3 插入和删除操作 AVL树:插入和删除后,树可能需要更多的旋转来恢复平衡,因此插入和删除的时间复杂度为O(log n),但常数因子较高。...红黑树:插入和删除操作相对简单,所需的旋转次数较少,性能上通常更快,时间复杂度为O(log n)。 6.4 内存使用 AVL树:每个节点需要存储额外的平衡因子,内存开销相对较大。

    7910

    深入理解AVL树:结构、旋转及C++实现

    AVL树是首个自平衡二叉搜索树,通过对树的平衡因子进行控制,确保任何节点的左右子树高度差最多为1,从而保证树的高度为对数级别,即 O(log⁡N)O(\log N)O(logN)。...在AVL树中,插入、删除和查找的时间复杂度都可以保持在 O(log⁡N)O(\log N)O(logN),这使得AVL树在需要频繁查询数据的应用场景中非常高效。...例如,按照递增顺序插入节点会使树的所有节点都集中在右边,导致高度等于节点数,查找复杂度为 O(N)O(N)O(N)。AVL树通过自动维护平衡性,避免了这种情况,确保所有操作的复杂度始终为对数级别。...树的查找操作 AVL树的查找操作和普通二叉搜索树类似,由于AVL树保持平衡,查找操作的时间复杂度始终为 O(log⁡N)O(\log N)O(logN)。...相比于普通的二叉搜索树,AVL树保证了每次操作的时间复杂度为 O(log⁡N)O(\log N)O(logN),特别适合频繁插入和删除的应用。 4.

    10010
    领券