AVL树如何在插入时平衡树

2024-01-15

我想为 avl 树创建一个插入函数。然而,插入函数必须是递归的并且必须是平衡的。

我有一个将树向左旋转的方法 PivoterAGauche 和一个将树向右旋转的方法 PivoterADroite。

    'Pivot left
    Private Function PivoterAGauche(leNoeud As NoeudAVL) As NoeudAVL
        If leNoeud Is Nothing Then
            Return Nothing
        ElseIf leNoeud.FilsDroit Is Nothing AndAlso leNoeud.FilsGauche Is Nothing Then
            Return leNoeud
        ElseIf leNoeud.FilsDroit Is Nothing Then
            Return leNoeud
            ' ElseIf leNoeud.FilsGauche Is Nothing Then

        Else 'Le leNoeud.FilsGauche existe.
            Dim pivot As NoeudAVL = leNoeud.FilsGauche
            leNoeud.FilsGauche = pivot.FilsDroit
            pivot.FilsDroit = leNoeud
            leNoeud = pivot
            Return leNoeud
        End If
    End Function

    'pivot rigth
    Private Function PivoterADroite(leNoeud As NoeudAVL) As NoeudAVL
        If leNoeud Is Nothing Then
            Return Nothing
        ElseIf leNoeud.FilsDroit Is Nothing AndAlso leNoeud.FilsGauche Is Nothing Then
            Return leNoeud
        ElseIf leNoeud.FilsDroit Is Nothing Then
            Return leNoeud
            ' ElseIf leNoeud.FilsGauche Is Nothing Then

        Else 'Le leNoeud.FilsGauche existe.
            Dim pivot As NoeudAVL = leNoeud.FilsDroit
            leNoeud.FilsDroit = pivot.FilsGauche
            pivot.FilsGauche = leNoeud
            leNoeud = pivot
            Return leNoeud
        End If
    End Function

这是我制作的插入方法。我不确定何时使用左右枢轴。

    Private Function Inserer(leElement As T, leNoeudCourant As NoeudAVL) As NoeudAVL

        Dim intBalance As Integer
        'If the node does not existes
        If leNoeudCourant Is Nothing Then
            m_blnOperationOK = True
            Return New NoeudAVL(leElement)
            'If the node already existes.
        ElseIf leElement.CompareTo(leNoeudCourant.Element) = 0 Then
            m_blnOperationOK = False
            Return leNoeudCourant
        ElseIf leElement.CompareTo(leNoeudCourant.Element) < 0 Then
            intBalance = Hauteur(leNoeudCourant.FilsGauche) - Hauteur(leNoeudCourant.FilsDroit)
            If (intBalance = 2) Then
                leNoeudCourant = PivoterAGauche(leNoeudCourant)
            End If
            leNoeudCourant.FilsGauche = Inserer(leElement, leNoeudCourant.FilsGauche)

        ElseIf leElement.CompareTo(leNoeudCourant.Element) > 0 Then
            intBalance = Hauteur(leNoeudCourant.FilsGauche) - Hauteur(leNoeudCourant.FilsDroit)
            If (intBalance = 2) Then
                leNoeudCourant = PivoterADroite(leNoeudCourant)
            End If
            leNoeudCourant.FilsDroit = Inserer(leElement, leNoeudCourant.FilsDroit)
        End If

        'Return current node that will become the root.
        Return leNoeudCourant

如果您有更多问题,我很乐意回答您的问题,感谢您的帮助。


让我们记住一些非常基本的事情:当在二叉树等任务中使用递归时,您的工作区是一个节点。这意味着该节点必须拥有完成您希望它执行的任务所需的一切。

你必须明白,从它自己的角度来看,每个节点都是它自己的树的根,有点像整个二叉树是由许多较小的二叉树构建的。 O 节点知道它的子节点,但不知道它的祖先。

为了能够构建平衡二叉树,您的节点必须能够“知道”这些事情:

  • 它们的高度(它们下面有多少个节点)。
  • 如果它们变得不平衡(当在当前评估的节点下,两个子节点的高度差都高于 1 级时)。

这里的魔力是强大的:一旦正确实现,二叉树将始终保持平衡,而不必完全重新评估自身。这是开动脑筋的时间。

首先,我们来处理高度:

每个节点都必须有一个高度值。该值必须作为模式变量存储在节点类中。使其成为公共属性,因为节点的父节点必须能够访问它。

Private _height As Integer = 0

Public ReadOnly Property Height As Integer
    Get
        Return _height
    End Get
End Property

当您插入第一个节点(根)时,它的高度为零。下面什么也没有。对于您创建的每个新节点都是如此。

当您插入另一个节点时,您通常“给出”要插入到根的值,然后让递归发挥它的魔力。现在在此操作过程中还有其他事情需要考虑:更新高度并纠正平衡。

Private Function insert(ByVal key As Integer, Optional node As Node = Nothing, ) As Node
    'if you are creating the root, node is nothing
    If (node Is Nothing) Then
        Return New Node(key)
    End If

    'creating new nodes when needed
    If (key < node.key) Then
        node.FilGauche = insert(key, node.FilGauche)
    ElseIf (key > node.key) Then
        node.FilDroit = insert(key, node.FilDroit)
    Else
        Return node
    End If

    're-evaluating height (accounting for null pointers) and then balancing the tree
    node._height = (1 + max(If(node.FilGauche.Height IsNot Nothing, node.FilGauche.Height, 0), node.FilDroit.Height IsNot Nothing, node.FilDroit.Height))
    Dim balance As Integer = If(node.FilGauche.Height IsNot Nothing, node.FilGauche.Height, 0) - If(node.FilDroit.Height IsNot Nothing, node.FilDroit.Height, 0)
    ' If this node becomes unbalanced, then there 
    ' are 4 cases Left Left Case 
    If ((balance > 1) AndAlso (key < node.FilGauche.key)) Then
        Return rightRotate(node)
    End If

    ' Right Right Case 
    If ((balance < -1) AndAlso (key > node.FilDroit.key)) Then
        Return leftRotate(node)
    End If

    ' Left Right Case 
    If ((balance > 1) AndAlso (key > node.FilGauche.key)) Then
        node.FilGauche = leftRotate(node.FilGauche)
        Return rightRotate(node)
    End If

    ' Right Left Case 
    If ((balance < -1) AndAlso (key < node.FilDroit.key)) Then
        node.FilDroit = rightRotate(node.FilDroit)
        Return leftRotate(node)
    End If

    Return node
End Function

当然,您必须根据您的具体情况调整这些想法,但这并不是唯一的事情:我正在使用另一种语言的参考文献并在 IDE 之外进行工作,因此我必须直接在浏览器中输入内容,这意味着我可能会写这篇文章时犯了一些错误。如果这没有意义,请告诉我,我会在更好的条件下仔细检查。祝你好运!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AVL树如何在插入时平衡树 的相关文章

  • VB.net 中 _ 下划线作为变量前缀的含义

    Visual Basic中下划线的含义是什么 我有这个代码 Private isAuthenticated As Boolean 这和这样做是一样的吗 Private isAuthenticated As Boolean 或者在名称前面添加
  • 用于确定应用程序是否在 Citrix 或终端服务上运行的 API [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个可以调用的 API 函数来确定软件是否在 Citrix 终端服务或独立 PC 上运行 最
  • 模式弹出窗口上的按钮单击事件,在网格视图内未触发

    我遇到以下问题 场景 我有一个 asp 网格 其中有一些绑定到数据的列 最后一列已转换为模板字段 在这个模板字段中有一个按钮 上面附加了一个模式弹出扩展器 该字段中隐藏着一个模式弹出窗口 此模式弹出窗口用于添加新帐户 它包含 2 个文本框
  • Python 递归和列表

    我正在学习 python 中的递归 我有以下代码 def search l key locates key in list l if present returns location as an index else returns Fal
  • 正则表达式引擎如何解析具有递归子模式的正则表达式?

    此正则表达式匹配回文 1 2 我无法理解它是如何工作的 递归何时结束 以及正则表达式何时从递归子模式中断并转到 part Thanks 编辑 抱歉我没有解释 2 and 1 1 指第一个子模式 对其自身 2 反向引用第二个子模式的匹配 即
  • Datagridview 单元格焦点

    我有一个从数据库加载数据的数据网格视图 这是未绑定的 datagridview 这些列是描述 价格 数量和总计 说明 U价格来自数据库 然后输入数量 我希望这样当我的数据网格加载时 光标会转到 数量 列 并且它会像我们在文本框中那样闪烁显示
  • 动态版本控制

    我有一种情况 我希望版本控制在构建时是动态的 版本图案
  • 使用 Python 的“哈密尔顿”路径

    我正在尝试使用 Python 实现遍历所有图顶点的任意路径 不一定是循环 的递归搜索 这是我的代码 def hamilton G size pt path if pt not in set path path append pt if le
  • 某些笔记本电脑中的 VB.net Forms UI 显示问题

    我是 VB 应用程序的新手 无法弄清楚我的应用程序出了什么问题 有一个带有几个标签和文本字段的表单 当我在我和其他人的机器上运行该应用程序时 它显示良好 并具有正确的对齐和字体 然而 对于某些人来说 应用程序表单 UI 是破碎的 未对齐的文
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 在javascript中访问隐藏字段值

    我的表单中有一个隐藏字段 我正在服务器上设置隐藏字段的值并尝试从 javascript 访问该值 我收到错误 无法获取属性 值 的值 对象为 null 或未定义 如果我查看源代码 则会设置隐藏字段值 并且隐藏字段的 ID 与我正在调用的 I
  • C# 的最佳替代“错误继续下一步”是什么?

    如果我为 C 代码放置空的 catch 块 它是否与 VB NET 的 On Error Resume Next 语句等效 try C code catch exception 我问这个问题的原因是因为我必须将 VB NET 代码转换为 C
  • 使一个对象只能被同一程序集中的另一个对象访问?

    每个业务对象都有一个包含 sql 调用的匹配对象 我想限制这些 sql 对象 使其只能由匹配的业务对象使用 如何才能实现这一目标 Update 格雷格提出了关于可测试性的观点 由于 SqlObjects 将包含非常特定于业务流程的 sql
  • 如何在vb.net中对datagridview的3列进行排序

    下面我想对 ProductCode ColorCode 和 Size 列进行排序 请指导 对 大小 列中的信息进行排序 Size Number sequence XS 1 S 2 M 3 L 4 XL 5 XXL 6 2L 7 3L 8 4
  • VB.NET 中的模块变量何时实例化?

    我想知道在程序的生命周期中 模块中的变量将被初始化 如下例所示 Module Helper Friend m Settings As New UserSettings Sub Foo End Sub Sub Bar End Sub End
  • 将嵌套数组中的“点符号”键扩展到子数组

    我从某个任意深度的嵌套数组开始 在该数组中 一些键是一系列由点分隔的标记 例如 billingAddress street 或 foo bar baz 我想将这些键控元素扩展到数组 因此结果是一个嵌套数组 其中所有这些键都已扩展 例如 bi
  • F# 之于 IronPython/IronRuby 就像 C# 之于 VB.NET 一样?

    我刚刚听了Chris Smith 谈论 F 的播客 http www code magazine com codecast index aspx messageid 7feb501f 25c8 432a 9624 97082f1e75e8他
  • 查找嵌套列表中元素的索引?

    我有一个类似的列表 mylist lt list a 1 b list A 1 B 2 c list C 1 D 3 是否有一种 无循环 方法来识别元素的位置 例如如果我想用 5 替换 C 的值 并且在哪里找到元素 C 并不重要 我可以这样
  • 我应该如何在 VB.NET 中进行转换?

    所有这些都相等吗 在什么情况下我应该选择其中一个而不是其他 var ToString CStr 变量 CType 变量 字符串 DirectCast 变量 字符串 编辑 来自的建议不是我自己 https stackoverflow com
  • 获取 FTP 服务器上的文件大小并将其放在标签上

    我正在尝试获取托管在FTP服务器并将其放入Label而 BackgroundWorker 在后台工作 我在用着 Try 来获取该值 但是该值在第一次尝试时被捕获 下载后 如果我按尝试再次获取它 那么它就可以工作 Note 第一次尝试时进度条

随机推荐

  • QTableWidget::itemAt() 返回看似随机的项目

    我刚刚开始使用 Qt 所以请耐心等待 当我使用 QTableWidget gt getItemAt 时 它返回的项目与我使用 currentItemChanged 并单击同一项目时不同 我相信有必要使用 itemAt 因为我需要获取单击的任
  • 首次设置 时 FacesContext#getViewRoot() 返回 null

    我正在尝试更改一页中的 JSF 应用程序区域设置 并且这必须更改我的所有页面区域设置 我已关注此链接 效果很好JSF 中的本地化 如何记住每个会话而不是每个请求 视图选择的区域设置 https stackoverflow com quest
  • 如何在 Java 中读取也具有空值的 Excel 单元格...?

    我正在使用 Apache POI 3 6 我有一个专栏是blank 我希望能够阅读它 然后转到下一栏 即使我能解决NullPointerException问题是我无法到达下一个牢房 这是我的代码片段 HSSFCell cell row ge
  • 从 Java 程序运行 SQL 文件脚本

    我有一组 SQL 文件可以转换我的原始数据集 目前 我打开每个文件并执行它 如何执行 Java 程序中的每个文件 目标是使这个过程更加自动化 我想做类似的事情SqlScript execute myScript sql NOTE这些 SQL
  • 为什么我们不能在堆栈上分配动态内存?

    在堆栈上分配内容非常棒 因为我们有 RAII 并且不必担心内存泄漏等问题 然而有时我们必须在堆上分配 如果数据真的很大 推荐 因为堆栈很小 如果要分配的数据的大小仅在运行时才知道 动态分配 两个问题 为什么我们不能分配动态内存 即大小为 仅
  • 节点 process.env 变量为空

    我正在构建我的第一个 Express 应用程序 它需要使用理想情况下保持安全的 API 密钥与 API 进行交互 所以我想遵循一个基本模式 将密钥 以及任何未来的环境变量 保存在一个 gitignored env根目录下的文件 为了不重新发
  • 如何绘制 (x,y,z)

    Is there anyway to plot x from x textbox y from y textbox and z from z textbox in vb form It is windows application I ha
  • 将文件名读入数组

    我想获取文件列表 然后将结果读入一个数组 其中每个数组元素对应一个文件名 这可能吗 不要使用ls it s 不打算 https mywiki wooledge org ParsingLs以此目的 使用通配符 shopt s nullglob
  • 如何使用findText不区分大小写?

    我尝试在 Google 文档中搜索字符串 默认情况下findText区分大小写 我该如何使用它不区分大小写 该参考文献称 使用正则表达式在元素内容中搜索指定的文本模式 这就是我尝试过的 function search string var
  • MongoDB C++,如何在插入时添加 ISODate 值

    这是关于新的 MongoDB C 驱动程序 不是旧版驱动程序 我可以这样插入文档 value Value document lt lt Key lt lt Value lt
  • .NET 中的字符串转换

    为什么 net中有这么多方法可以转换为字符串 我见过的方法是 ToString Convert ToString 和 string 有什么不同 Convert ToString obj 将指定值转换为其等效的字符串表示形式 将返回Strin
  • 调整 GC 以进行大型缓存刷新

    我的内存中有一个很大的缓存 使用com google common cache LoadingCache 使用 Scheduler 会在 10 分钟后刷新 如下所示 ScheduledExecutorService refresher Ex
  • Mac OS X 10.9 - 设置永久环境变量

    如何在 Mac OS X 10 9 中设置永久环境变量 即每次启动新终端会话时不需要导出的环境变量 我找到了许多关于修改我的答案 bash profile and profile然而 这两种选择似乎都不是永久的解决方案 只是暂时的 我试图设
  • 我应该将 SQL 查询放在 Rails 中的哪里?

    我应该在 Rails 中的什么位置放置 SQL 查询的最佳实践是什么 我是否应该在模型中创建方法 例如 find all public items 其中我在所有条件下使用查找方法 然后在控制器中使用它们 就像这样 我将所有查询都放在一个地方
  • 为什么占位符伪元素上的转换属性在 Chrome 中有效?

    我正在闲逛 placeholder当我注意到一些奇怪的事情时 Codepen Chrome 59 0 3071 上的伪元素 请看我的JSFiddle https jsfiddle net 4ct6zkaw 简而言之 此 CSS 不应启用 p
  • 红外 LED 跟踪:使用 OpenCV 跟踪 x、y、z 位置

    我正在寻找一种方法来解决我遇到的计算机视觉问题 我有工作跟踪系统 4 8个摄像头 给出红外 LED 的 x y z 每个 LED 传输独特的 8 位信号 跟踪系统价格昂贵 而且界面对于我们的用户来说太难使用 我想用我自己的 OpenCV 实
  • 按钮垂直对齐引导程序

    我正在尝试以简单的形式对齐按钮 我这样做了 div class panel panel default div class panel heading teste div div class panel body div class row
  • 将应用程序提交到使用 Firebase 的 App Store

    我有一个关于在使用 Firebase 时向应用程序商店提交应用程序的快速问题 我想知道 Firebase 方面是否需要做任何事情才能使数据库可供任何人使用 或者我可以只完成提交应用程序的正常过程并假设数据库将为测试人员或下载该应用程序的任何
  • std::includes 实际上做了什么?

    From 标准 https timsong cpp github io cppwp n4659 alg set operations includes std includes 返回 true if first2 last2 为空或者范围内
  • AVL树如何在插入时平衡树

    我想为 avl 树创建一个插入函数 然而 插入函数必须是递归的并且必须是平衡的 我有一个将树向左旋转的方法 PivoterAGauche 和一个将树向右旋转的方法 PivoterADroite Pivot left Private Func