|
|
1
74
第1部分-高度正如Starblue所说,高度只是递归的。在伪代码中:
现在高度可以用两种方式定义。它可以是从根节点到该节点的路径中的节点数,也可以是链接数。根据 page you referenced ,最常见的定义是链接数。在这种情况下,完整的伪代码是:
如果需要节点数,则代码为:
不管怎样,我认为重新平衡算法的工作原理应该是一样的。 但是,你的树会更有效率( O(Ln(n)) )如果您在树中存储和更新高度信息,而不是每次计算高度信息。( o(n) ) 第2部分-平衡当它说“如果r的平衡因子是1”时,它指的是右分支的平衡因子,当顶部的平衡因子是2时。它告诉您如何选择是进行单次旋转还是进行双次旋转。在(类似于python的)伪代码中:
我希望这有道理 |
|
|
2
4
|
|
|
3
3
您不需要动态计算树的深度。 您可以在执行操作时维护它们。 此外,实际上您不必维护深度跟踪;您只需跟踪左树深度和右树深度之间的差异。 http://www.eternallyconfuzzled.com/tuts/datastructures/jsw_tut_avl.aspx 在编程POV中,只需跟踪平衡因子(左、右子树之间的差异)就比较容易了,除了在旋转后整理平衡因子是一个pita… |
|
|
4
2
这是另一种寻找高度的方法。向节点添加一个名为height的附加属性:
现在,我们将对树进行简单的宽度优先遍历,并不断更新每个节点的高度值:
干杯, |
|
|
5
1
好吧,可以用下面的递归函数计算树的高度:
有适当的定义
然而,对于像AVL树这样的东西,我认为你不需要每次需要它时都计算高度。相反,每一个树节点都会增加一个额外的字段来记住在该节点上根的子树的高度。此字段必须保持最新,因为树是通过插入和删除来修改的。 我怀疑,如果您每次都计算高度,而不是像上面建议的那样将其缓存在树中,那么AVL树的形状将是正确的,但它不会具有预期的对数性能。 |
|
|
6
1
如果
|
|
|
7
1
好的,顿悟时间。 考虑旋转的作用。让我们考虑一下左旋转。
现在,你必须注意到的一件大事——左旋转并没有改变树的深度。我们做了这件事再也不平衡了。 但是-这里是AVL的魔力-如果我们先把正确的孩子旋转到正确的位置,我们会得到这个…
如果我们向左旋转,我们得到的是…
魔术!我们已经设法把树的一层去掉了。- 我们使树保持平衡 . 平衡这棵树意味着去除多余的深度,更完整地包装上层——这正是我们刚刚做的。 关于单/双旋转的全部内容就是你必须让你的子树看起来像这样;
在你旋转之前-你可能要做一个正确的旋转才能进入那个状态。但如果你已经处于这种状态,你只需要做左旋转。 |
|
|
8
0
给予
请注意,数据成员
如果要删除节点,请使用其他版本的
哪里
以下是整个代码: http://ideone.com/d6arrv |
|
|
9
0
这种类似BFS的解决方案非常简单。只需一个接一个地跳过级别。
|
|
|
Zevvysan · 为什么我的打印函数之一要删除节点? 7 年前 |
|
|
user9573040 · 递归二叉树高度 7 年前 |
|
|
Dipesh Desai · 在二叉树haskell中搜索值 7 年前 |
|
|
ibrahim · “main”已停止工作-C++[开发人员++] 7 年前 |