mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-25 04:26:07 +00:00
deploy
This commit is contained in:
@@ -1469,15 +1469,15 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_1" class="md-nav__link">
|
||||
节点高度
|
||||
<a href="#1" class="md-nav__link">
|
||||
1. 节点高度
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_2" class="md-nav__link">
|
||||
节点平衡因子
|
||||
<a href="#2" class="md-nav__link">
|
||||
2. 节点平衡因子
|
||||
</a>
|
||||
|
||||
</li>
|
||||
@@ -1496,36 +1496,36 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_3" class="md-nav__link">
|
||||
右旋
|
||||
<a href="#1_1" class="md-nav__link">
|
||||
1. 右旋
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_4" class="md-nav__link">
|
||||
左旋
|
||||
<a href="#2_1" class="md-nav__link">
|
||||
2. 左旋
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_5" class="md-nav__link">
|
||||
先左旋后右旋
|
||||
<a href="#3" class="md-nav__link">
|
||||
3. 先左旋后右旋
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_6" class="md-nav__link">
|
||||
先右旋后左旋
|
||||
<a href="#4" class="md-nav__link">
|
||||
4. 先右旋后左旋
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_7" class="md-nav__link">
|
||||
旋转的选择
|
||||
<a href="#5" class="md-nav__link">
|
||||
5. 旋转的选择
|
||||
</a>
|
||||
|
||||
</li>
|
||||
@@ -1544,22 +1544,22 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_8" class="md-nav__link">
|
||||
插入节点
|
||||
<a href="#1_2" class="md-nav__link">
|
||||
1. 插入节点
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_9" class="md-nav__link">
|
||||
删除节点
|
||||
<a href="#2_2" class="md-nav__link">
|
||||
2. 删除节点
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_10" class="md-nav__link">
|
||||
查找节点
|
||||
<a href="#3_1" class="md-nav__link">
|
||||
3. 查找节点
|
||||
</a>
|
||||
|
||||
</li>
|
||||
@@ -3485,15 +3485,15 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_1" class="md-nav__link">
|
||||
节点高度
|
||||
<a href="#1" class="md-nav__link">
|
||||
1. 节点高度
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_2" class="md-nav__link">
|
||||
节点平衡因子
|
||||
<a href="#2" class="md-nav__link">
|
||||
2. 节点平衡因子
|
||||
</a>
|
||||
|
||||
</li>
|
||||
@@ -3512,36 +3512,36 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_3" class="md-nav__link">
|
||||
右旋
|
||||
<a href="#1_1" class="md-nav__link">
|
||||
1. 右旋
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_4" class="md-nav__link">
|
||||
左旋
|
||||
<a href="#2_1" class="md-nav__link">
|
||||
2. 左旋
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_5" class="md-nav__link">
|
||||
先左旋后右旋
|
||||
<a href="#3" class="md-nav__link">
|
||||
3. 先左旋后右旋
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_6" class="md-nav__link">
|
||||
先右旋后左旋
|
||||
<a href="#4" class="md-nav__link">
|
||||
4. 先右旋后左旋
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_7" class="md-nav__link">
|
||||
旋转的选择
|
||||
<a href="#5" class="md-nav__link">
|
||||
5. 旋转的选择
|
||||
</a>
|
||||
|
||||
</li>
|
||||
@@ -3560,22 +3560,22 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_8" class="md-nav__link">
|
||||
插入节点
|
||||
<a href="#1_2" class="md-nav__link">
|
||||
1. 插入节点
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_9" class="md-nav__link">
|
||||
删除节点
|
||||
<a href="#2_2" class="md-nav__link">
|
||||
2. 删除节点
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_10" class="md-nav__link">
|
||||
查找节点
|
||||
<a href="#3_1" class="md-nav__link">
|
||||
3. 查找节点
|
||||
</a>
|
||||
|
||||
</li>
|
||||
@@ -3628,7 +3628,7 @@
|
||||
<p>G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorithm for the organization of information" 中提出了「AVL 树」。论文中详细描述了一系列操作,确保在持续添加和删除节点后,AVL 树不会退化,从而使得各种操作的时间复杂度保持在 <span class="arithmatex">\(O(\log n)\)</span> 级别。换句话说,在需要频繁进行增删查改操作的场景中,AVL 树能始终保持高效的数据操作性能,具有很好的应用价值。</p>
|
||||
<h2 id="751-avl">7.5.1 AVL 树常见术语<a class="headerlink" href="#751-avl" title="Permanent link">¶</a></h2>
|
||||
<p>「AVL 树」既是二叉搜索树也是平衡二叉树,同时满足这两类二叉树的所有性质,因此也被称为「平衡二叉搜索树」。</p>
|
||||
<h3 id="_1">节点高度<a class="headerlink" href="#_1" title="Permanent link">¶</a></h3>
|
||||
<h3 id="1">1. 节点高度<a class="headerlink" href="#1" title="Permanent link">¶</a></h3>
|
||||
<p>在操作 AVL 树时,我们需要获取节点的高度,因此需要为 AVL 树的节点类添加 <code>height</code> 变量。</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="1:12"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><input id="__tabbed_1_6" name="__tabbed_1" type="radio" /><input id="__tabbed_1_7" name="__tabbed_1" type="radio" /><input id="__tabbed_1_8" name="__tabbed_1" type="radio" /><input id="__tabbed_1_9" name="__tabbed_1" type="radio" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><input id="__tabbed_1_12" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Java</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Python</label><label for="__tabbed_1_4">Go</label><label for="__tabbed_1_5">JS</label><label for="__tabbed_1_6">TS</label><label for="__tabbed_1_7">C</label><label for="__tabbed_1_8">C#</label><label for="__tabbed_1_9">Swift</label><label for="__tabbed_1_10">Zig</label><label for="__tabbed_1_11">Dart</label><label for="__tabbed_1_12">Rust</label></div>
|
||||
<div class="tabbed-content">
|
||||
@@ -3979,7 +3979,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 id="_2">节点平衡因子<a class="headerlink" href="#_2" title="Permanent link">¶</a></h3>
|
||||
<h3 id="2">2. 节点平衡因子<a class="headerlink" href="#2" title="Permanent link">¶</a></h3>
|
||||
<p>节点的「平衡因子 Balance Factor」定义为节点左子树的高度减去右子树的高度,同时规定空节点的平衡因子为 0 。我们同样将获取节点平衡因子的功能封装成函数,方便后续使用。</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="3:12"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><input id="__tabbed_3_3" name="__tabbed_3" type="radio" /><input id="__tabbed_3_4" name="__tabbed_3" type="radio" /><input id="__tabbed_3_5" name="__tabbed_3" type="radio" /><input id="__tabbed_3_6" name="__tabbed_3" type="radio" /><input id="__tabbed_3_7" name="__tabbed_3" type="radio" /><input id="__tabbed_3_8" name="__tabbed_3" type="radio" /><input id="__tabbed_3_9" name="__tabbed_3" type="radio" /><input id="__tabbed_3_10" name="__tabbed_3" type="radio" /><input id="__tabbed_3_11" name="__tabbed_3" type="radio" /><input id="__tabbed_3_12" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">Java</label><label for="__tabbed_3_2">C++</label><label for="__tabbed_3_3">Python</label><label for="__tabbed_3_4">Go</label><label for="__tabbed_3_5">JS</label><label for="__tabbed_3_6">TS</label><label for="__tabbed_3_7">C</label><label for="__tabbed_3_8">C#</label><label for="__tabbed_3_9">Swift</label><label for="__tabbed_3_10">Zig</label><label for="__tabbed_3_11">Dart</label><label for="__tabbed_3_12">Rust</label></div>
|
||||
<div class="tabbed-content">
|
||||
@@ -4122,7 +4122,7 @@
|
||||
<h2 id="752-avl">7.5.2 AVL 树旋转<a class="headerlink" href="#752-avl" title="Permanent link">¶</a></h2>
|
||||
<p>AVL 树的特点在于「旋转 Rotation」操作,它能够在不影响二叉树的中序遍历序列的前提下,使失衡节点重新恢复平衡。换句话说,<strong>旋转操作既能保持树的「二叉搜索树」属性,也能使树重新变为「平衡二叉树」</strong>。</p>
|
||||
<p>我们将平衡因子绝对值 <span class="arithmatex">\(> 1\)</span> 的节点称为「失衡节点」。根据节点失衡情况的不同,旋转操作分为四种:右旋、左旋、先右旋后左旋、先左旋后右旋。下面我们将详细介绍这些旋转操作。</p>
|
||||
<h3 id="_3">右旋<a class="headerlink" href="#_3" title="Permanent link">¶</a></h3>
|
||||
<h3 id="1_1">1. 右旋<a class="headerlink" href="#1_1" title="Permanent link">¶</a></h3>
|
||||
<p>如下图所示,节点下方为平衡因子。从底至顶看,二叉树中首个失衡节点是“节点 3”。我们关注以该失衡节点为根节点的子树,将该节点记为 <code>node</code> ,其左子节点记为 <code>child</code> ,执行「右旋」操作。完成右旋后,子树已经恢复平衡,并且仍然保持二叉搜索树的特性。</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="4:4"><input checked="checked" id="__tabbed_4_1" name="__tabbed_4" type="radio" /><input id="__tabbed_4_2" name="__tabbed_4" type="radio" /><input id="__tabbed_4_3" name="__tabbed_4" type="radio" /><input id="__tabbed_4_4" name="__tabbed_4" type="radio" /><div class="tabbed-labels"><label for="__tabbed_4_1"><1></label><label for="__tabbed_4_2"><2></label><label for="__tabbed_4_3"><3></label><label for="__tabbed_4_4"><4></label></div>
|
||||
<div class="tabbed-content">
|
||||
@@ -4348,7 +4348,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 id="_4">左旋<a class="headerlink" href="#_4" title="Permanent link">¶</a></h3>
|
||||
<h3 id="2_1">2. 左旋<a class="headerlink" href="#2_1" title="Permanent link">¶</a></h3>
|
||||
<p>相应的,如果考虑上述失衡二叉树的“镜像”,则需要执行「左旋」操作。</p>
|
||||
<p><img alt="左旋操作" src="../avl_tree.assets/avltree_left_rotate.png" /></p>
|
||||
<p align="center"> 图:左旋操作 </p>
|
||||
@@ -4559,17 +4559,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 id="_5">先左旋后右旋<a class="headerlink" href="#_5" title="Permanent link">¶</a></h3>
|
||||
<h3 id="3">3. 先左旋后右旋<a class="headerlink" href="#3" title="Permanent link">¶</a></h3>
|
||||
<p>对于下图中的失衡节点 3,仅使用左旋或右旋都无法使子树恢复平衡。此时需要先左旋后右旋,即先对 <code>child</code> 执行「左旋」,再对 <code>node</code> 执行「右旋」。</p>
|
||||
<p><img alt="先左旋后右旋" src="../avl_tree.assets/avltree_left_right_rotate.png" /></p>
|
||||
<p align="center"> 图:先左旋后右旋 </p>
|
||||
|
||||
<h3 id="_6">先右旋后左旋<a class="headerlink" href="#_6" title="Permanent link">¶</a></h3>
|
||||
<h3 id="4">4. 先右旋后左旋<a class="headerlink" href="#4" title="Permanent link">¶</a></h3>
|
||||
<p>同理,对于上述失衡二叉树的镜像情况,需要先右旋后左旋,即先对 <code>child</code> 执行「右旋」,然后对 <code>node</code> 执行「左旋」。</p>
|
||||
<p><img alt="先右旋后左旋" src="../avl_tree.assets/avltree_right_left_rotate.png" /></p>
|
||||
<p align="center"> 图:先右旋后左旋 </p>
|
||||
|
||||
<h3 id="_7">旋转的选择<a class="headerlink" href="#_7" title="Permanent link">¶</a></h3>
|
||||
<h3 id="5">5. 旋转的选择<a class="headerlink" href="#5" title="Permanent link">¶</a></h3>
|
||||
<p>下图展示的四种失衡情况与上述案例逐个对应,分别需要采用右旋、左旋、先右后左、先左后右的旋转操作。</p>
|
||||
<p><img alt="AVL 树的四种旋转情况" src="../avl_tree.assets/avltree_rotation_cases.png" /></p>
|
||||
<p align="center"> 图:AVL 树的四种旋转情况 </p>
|
||||
@@ -5001,7 +5001,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<h2 id="753-avl">7.5.3 AVL 树常用操作<a class="headerlink" href="#753-avl" title="Permanent link">¶</a></h2>
|
||||
<h3 id="_8">插入节点<a class="headerlink" href="#_8" title="Permanent link">¶</a></h3>
|
||||
<h3 id="1_2">1. 插入节点<a class="headerlink" href="#1_2" title="Permanent link">¶</a></h3>
|
||||
<p>「AVL 树」的节点插入操作与「二叉搜索树」在主体上类似。唯一的区别在于,在 AVL 树中插入节点后,从该节点到根节点的路径上可能会出现一系列失衡节点。因此,<strong>我们需要从这个节点开始,自底向上执行旋转操作,使所有失衡节点恢复平衡</strong>。</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="8:12"><input checked="checked" id="__tabbed_8_1" name="__tabbed_8" type="radio" /><input id="__tabbed_8_2" name="__tabbed_8" type="radio" /><input id="__tabbed_8_3" name="__tabbed_8" type="radio" /><input id="__tabbed_8_4" name="__tabbed_8" type="radio" /><input id="__tabbed_8_5" name="__tabbed_8" type="radio" /><input id="__tabbed_8_6" name="__tabbed_8" type="radio" /><input id="__tabbed_8_7" name="__tabbed_8" type="radio" /><input id="__tabbed_8_8" name="__tabbed_8" type="radio" /><input id="__tabbed_8_9" name="__tabbed_8" type="radio" /><input id="__tabbed_8_10" name="__tabbed_8" type="radio" /><input id="__tabbed_8_11" name="__tabbed_8" type="radio" /><input id="__tabbed_8_12" name="__tabbed_8" type="radio" /><div class="tabbed-labels"><label for="__tabbed_8_1">Java</label><label for="__tabbed_8_2">C++</label><label for="__tabbed_8_3">Python</label><label for="__tabbed_8_4">Go</label><label for="__tabbed_8_5">JS</label><label for="__tabbed_8_6">TS</label><label for="__tabbed_8_7">C</label><label for="__tabbed_8_8">C#</label><label for="__tabbed_8_9">Swift</label><label for="__tabbed_8_10">Zig</label><label for="__tabbed_8_11">Dart</label><label for="__tabbed_8_12">Rust</label></div>
|
||||
<div class="tabbed-content">
|
||||
@@ -5331,7 +5331,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 id="_9">删除节点<a class="headerlink" href="#_9" title="Permanent link">¶</a></h3>
|
||||
<h3 id="2_2">2. 删除节点<a class="headerlink" href="#2_2" title="Permanent link">¶</a></h3>
|
||||
<p>类似地,在二叉搜索树的删除节点方法的基础上,需要从底至顶地执行旋转操作,使所有失衡节点恢复平衡。</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="9:12"><input checked="checked" id="__tabbed_9_1" name="__tabbed_9" type="radio" /><input id="__tabbed_9_2" name="__tabbed_9" type="radio" /><input id="__tabbed_9_3" name="__tabbed_9" type="radio" /><input id="__tabbed_9_4" name="__tabbed_9" type="radio" /><input id="__tabbed_9_5" name="__tabbed_9" type="radio" /><input id="__tabbed_9_6" name="__tabbed_9" type="radio" /><input id="__tabbed_9_7" name="__tabbed_9" type="radio" /><input id="__tabbed_9_8" name="__tabbed_9" type="radio" /><input id="__tabbed_9_9" name="__tabbed_9" type="radio" /><input id="__tabbed_9_10" name="__tabbed_9" type="radio" /><input id="__tabbed_9_11" name="__tabbed_9" type="radio" /><input id="__tabbed_9_12" name="__tabbed_9" type="radio" /><div class="tabbed-labels"><label for="__tabbed_9_1">Java</label><label for="__tabbed_9_2">C++</label><label for="__tabbed_9_3">Python</label><label for="__tabbed_9_4">Go</label><label for="__tabbed_9_5">JS</label><label for="__tabbed_9_6">TS</label><label for="__tabbed_9_7">C</label><label for="__tabbed_9_8">C#</label><label for="__tabbed_9_9">Swift</label><label for="__tabbed_9_10">Zig</label><label for="__tabbed_9_11">Dart</label><label for="__tabbed_9_12">Rust</label></div>
|
||||
<div class="tabbed-content">
|
||||
@@ -5868,7 +5868,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 id="_10">查找节点<a class="headerlink" href="#_10" title="Permanent link">¶</a></h3>
|
||||
<h3 id="3_1">3. 查找节点<a class="headerlink" href="#3_1" title="Permanent link">¶</a></h3>
|
||||
<p>AVL 树的节点查找操作与二叉搜索树一致,在此不再赘述。</p>
|
||||
<h2 id="754-avl">7.5.4 AVL 树典型应用<a class="headerlink" href="#754-avl" title="Permanent link">¶</a></h2>
|
||||
<ul>
|
||||
|
||||
@@ -1449,29 +1449,29 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_1" class="md-nav__link">
|
||||
查找节点
|
||||
<a href="#1" class="md-nav__link">
|
||||
1. 查找节点
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_2" class="md-nav__link">
|
||||
插入节点
|
||||
<a href="#2" class="md-nav__link">
|
||||
2. 插入节点
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_3" class="md-nav__link">
|
||||
删除节点
|
||||
<a href="#3" class="md-nav__link">
|
||||
3. 删除节点
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_4" class="md-nav__link">
|
||||
排序
|
||||
<a href="#4" class="md-nav__link">
|
||||
4. 排序
|
||||
</a>
|
||||
|
||||
</li>
|
||||
@@ -3424,29 +3424,29 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_1" class="md-nav__link">
|
||||
查找节点
|
||||
<a href="#1" class="md-nav__link">
|
||||
1. 查找节点
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_2" class="md-nav__link">
|
||||
插入节点
|
||||
<a href="#2" class="md-nav__link">
|
||||
2. 插入节点
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_3" class="md-nav__link">
|
||||
删除节点
|
||||
<a href="#3" class="md-nav__link">
|
||||
3. 删除节点
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_4" class="md-nav__link">
|
||||
排序
|
||||
<a href="#4" class="md-nav__link">
|
||||
4. 排序
|
||||
</a>
|
||||
|
||||
</li>
|
||||
@@ -3504,7 +3504,7 @@
|
||||
|
||||
<h2 id="741">7.4.1 二叉搜索树的操作<a class="headerlink" href="#741" title="Permanent link">¶</a></h2>
|
||||
<p>我们将二叉搜索树封装为一个类 <code>ArrayBinaryTree</code> ,并声明一个成员变量 <code>root</code> ,指向树的根节点。</p>
|
||||
<h3 id="_1">查找节点<a class="headerlink" href="#_1" title="Permanent link">¶</a></h3>
|
||||
<h3 id="1">1. 查找节点<a class="headerlink" href="#1" title="Permanent link">¶</a></h3>
|
||||
<p>给定目标节点值 <code>num</code> ,可以根据二叉搜索树的性质来查找。我们声明一个节点 <code>cur</code> ,从二叉树的根节点 <code>root</code> 出发,循环比较节点值 <code>cur.val</code> 和 <code>num</code> 之间的大小关系</p>
|
||||
<ul>
|
||||
<li>若 <code>cur.val < num</code> ,说明目标节点在 <code>cur</code> 的右子树中,因此执行 <code>cur = cur.right</code> 。</li>
|
||||
@@ -3788,7 +3788,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 id="_2">插入节点<a class="headerlink" href="#_2" title="Permanent link">¶</a></h3>
|
||||
<h3 id="2">2. 插入节点<a class="headerlink" href="#2" title="Permanent link">¶</a></h3>
|
||||
<p>给定一个待插入元素 <code>num</code> ,为了保持二叉搜索树“左子树 < 根节点 < 右子树”的性质,插入操作分为两步:</p>
|
||||
<ol>
|
||||
<li><strong>查找插入位置</strong>:与查找操作相似,从根节点出发,根据当前节点值和 <code>num</code> 的大小关系循环向下搜索,直到越过叶节点(遍历至 <span class="arithmatex">\(\text{None}\)</span> )时跳出循环。</li>
|
||||
@@ -4172,7 +4172,7 @@
|
||||
</div>
|
||||
<p>为了插入节点,我们需要利用辅助节点 <code>pre</code> 保存上一轮循环的节点,这样在遍历至 <span class="arithmatex">\(\text{None}\)</span> 时,我们可以获取到其父节点,从而完成节点插入操作。</p>
|
||||
<p>与查找节点相同,插入节点使用 <span class="arithmatex">\(O(\log n)\)</span> 时间。</p>
|
||||
<h3 id="_3">删除节点<a class="headerlink" href="#_3" title="Permanent link">¶</a></h3>
|
||||
<h3 id="3">3. 删除节点<a class="headerlink" href="#3" title="Permanent link">¶</a></h3>
|
||||
<p>与插入节点类似,我们需要在删除操作后维持二叉搜索树的“左子树 < 根节点 < 右子树”的性质。首先,我们需要在二叉树中执行查找操作,获取待删除节点。接下来,根据待删除节点的子节点数量,删除操作需分为三种情况:</p>
|
||||
<p>当待删除节点的度为 <span class="arithmatex">\(0\)</span> 时,表示待删除节点是叶节点,可以直接删除。</p>
|
||||
<p><img alt="在二叉搜索树中删除节点(度为 0)" src="../binary_search_tree.assets/bst_remove_case1.png" /></p>
|
||||
@@ -4898,7 +4898,7 @@ void insert(int num) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 id="_4">排序<a class="headerlink" href="#_4" title="Permanent link">¶</a></h3>
|
||||
<h3 id="4">4. 排序<a class="headerlink" href="#4" title="Permanent link">¶</a></h3>
|
||||
<p>我们知道,二叉树的中序遍历遵循“左 <span class="arithmatex">\(\rightarrow\)</span> 根 <span class="arithmatex">\(\rightarrow\)</span> 右”的遍历顺序,而二叉搜索树满足“左子节点 <span class="arithmatex">\(<\)</span> 根节点 <span class="arithmatex">\(<\)</span> 右子节点”的大小关系。因此,在二叉搜索树中进行中序遍历时,总是会优先遍历下一个最小节点,从而得出一个重要性质:<strong>二叉搜索树的中序遍历序列是升序的</strong>。</p>
|
||||
<p>利用中序遍历升序的性质,我们在二叉搜索树中获取有序数据仅需 <span class="arithmatex">\(O(n)\)</span> 时间,无需额外排序,非常高效。</p>
|
||||
<p><img alt="二叉搜索树的中序遍历序列" src="../binary_search_tree.assets/bst_inorder_traversal.png" /></p>
|
||||
|
||||
@@ -1403,29 +1403,29 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_1" class="md-nav__link">
|
||||
完美二叉树
|
||||
<a href="#1" class="md-nav__link">
|
||||
1. 完美二叉树
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_2" class="md-nav__link">
|
||||
完全二叉树
|
||||
<a href="#2" class="md-nav__link">
|
||||
2. 完全二叉树
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_3" class="md-nav__link">
|
||||
完满二叉树
|
||||
<a href="#3" class="md-nav__link">
|
||||
3. 完满二叉树
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_4" class="md-nav__link">
|
||||
平衡二叉树
|
||||
<a href="#4" class="md-nav__link">
|
||||
4. 平衡二叉树
|
||||
</a>
|
||||
|
||||
</li>
|
||||
@@ -3445,29 +3445,29 @@
|
||||
<ul class="md-nav__list">
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_1" class="md-nav__link">
|
||||
完美二叉树
|
||||
<a href="#1" class="md-nav__link">
|
||||
1. 完美二叉树
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_2" class="md-nav__link">
|
||||
完全二叉树
|
||||
<a href="#2" class="md-nav__link">
|
||||
2. 完全二叉树
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_3" class="md-nav__link">
|
||||
完满二叉树
|
||||
<a href="#3" class="md-nav__link">
|
||||
3. 完满二叉树
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#_4" class="md-nav__link">
|
||||
平衡二叉树
|
||||
<a href="#4" class="md-nav__link">
|
||||
4. 平衡二叉树
|
||||
</a>
|
||||
|
||||
</li>
|
||||
@@ -3953,7 +3953,7 @@
|
||||
<p>需要注意的是,插入节点可能会改变二叉树的原有逻辑结构,而删除节点通常意味着删除该节点及其所有子树。因此,在二叉树中,插入与删除操作通常是由一套操作配合完成的,以实现有实际意义的操作。</p>
|
||||
</div>
|
||||
<h2 id="713">7.1.3 常见二叉树类型<a class="headerlink" href="#713" title="Permanent link">¶</a></h2>
|
||||
<h3 id="_1">完美二叉树<a class="headerlink" href="#_1" title="Permanent link">¶</a></h3>
|
||||
<h3 id="1">1. 完美二叉树<a class="headerlink" href="#1" title="Permanent link">¶</a></h3>
|
||||
<p>「完美二叉树 Perfect Binary Tree」除了最底层外,其余所有层的节点都被完全填满。在完美二叉树中,叶节点的度为 <span class="arithmatex">\(0\)</span> ,其余所有节点的度都为 <span class="arithmatex">\(2\)</span> ;若树高度为 <span class="arithmatex">\(h\)</span> ,则节点总数为 <span class="arithmatex">\(2^{h+1} - 1\)</span> ,呈现标准的指数级关系,反映了自然界中常见的细胞分裂现象。</p>
|
||||
<div class="admonition tip">
|
||||
<p class="admonition-title">Tip</p>
|
||||
@@ -3962,17 +3962,17 @@
|
||||
<p><img alt="完美二叉树" src="../binary_tree.assets/perfect_binary_tree.png" /></p>
|
||||
<p align="center"> 图:完美二叉树 </p>
|
||||
|
||||
<h3 id="_2">完全二叉树<a class="headerlink" href="#_2" title="Permanent link">¶</a></h3>
|
||||
<h3 id="2">2. 完全二叉树<a class="headerlink" href="#2" title="Permanent link">¶</a></h3>
|
||||
<p>「完全二叉树 Complete Binary Tree」只有最底层的节点未被填满,且最底层节点尽量靠左填充。</p>
|
||||
<p><img alt="完全二叉树" src="../binary_tree.assets/complete_binary_tree.png" /></p>
|
||||
<p align="center"> 图:完全二叉树 </p>
|
||||
|
||||
<h3 id="_3">完满二叉树<a class="headerlink" href="#_3" title="Permanent link">¶</a></h3>
|
||||
<h3 id="3">3. 完满二叉树<a class="headerlink" href="#3" title="Permanent link">¶</a></h3>
|
||||
<p>「完满二叉树 Full Binary Tree」除了叶节点之外,其余所有节点都有两个子节点。</p>
|
||||
<p><img alt="完满二叉树" src="../binary_tree.assets/full_binary_tree.png" /></p>
|
||||
<p align="center"> 图:完满二叉树 </p>
|
||||
|
||||
<h3 id="_4">平衡二叉树<a class="headerlink" href="#_4" title="Permanent link">¶</a></h3>
|
||||
<h3 id="4">4. 平衡二叉树<a class="headerlink" href="#4" title="Permanent link">¶</a></h3>
|
||||
<p>「平衡二叉树 Balanced Binary Tree」中任意节点的左子树和右子树的高度之差的绝对值不超过 1 。</p>
|
||||
<p><img alt="平衡二叉树" src="../binary_tree.assets/balanced_binary_tree.png" /></p>
|
||||
<p align="center"> 图:平衡二叉树 </p>
|
||||
|
||||
Reference in New Issue
Block a user