mirror of
https://github.com/krahets/hello-algo.git
synced 2025-07-13 10:42:08 +08:00
deploy
This commit is contained in:
@ -3524,7 +3524,7 @@
|
||||
|
||||
|
||||
<h1 id="81">8.1 堆<a class="headerlink" href="#81" title="Permanent link">¶</a></h1>
|
||||
<p>「堆 heap」是一种满足特定条件的完全二叉树,主要可分为图 8-1 所示的两种类型:</p>
|
||||
<p>「堆 heap」是一种满足特定条件的完全二叉树,主要可分为图 8-1 所示的两种类型。</p>
|
||||
<ul>
|
||||
<li>「大顶堆 max heap」:任意节点的值 <span class="arithmatex">\(\geq\)</span> 其子节点的值。</li>
|
||||
<li>「小顶堆 min heap」:任意节点的值 <span class="arithmatex">\(\leq\)</span> 其子节点的值。</li>
|
||||
@ -3532,7 +3532,7 @@
|
||||
<p><img alt="小顶堆与大顶堆" src="../heap.assets/min_heap_and_max_heap.png" /></p>
|
||||
<p align="center"> 图 8-1 小顶堆与大顶堆 </p>
|
||||
|
||||
<p>堆作为完全二叉树的一个特例,具有以下特性:</p>
|
||||
<p>堆作为完全二叉树的一个特例,具有以下特性。</p>
|
||||
<ul>
|
||||
<li>最底层节点靠左填充,其他层的节点都被填满。</li>
|
||||
<li>我们将二叉树的根节点称为“堆顶”,将底层最靠右的节点称为“堆底”。</li>
|
||||
@ -4501,7 +4501,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<h3 id="4">4. 堆顶元素出堆<a class="headerlink" href="#4" title="Permanent link">¶</a></h3>
|
||||
<p>堆顶元素是二叉树的根节点,即列表首元素。如果我们直接从列表中删除首元素,那么二叉树中所有节点的索引都会发生变化,这将使得后续使用堆化修复变得困难。为了尽量减少元素索引的变动,我们采取以下操作步骤:</p>
|
||||
<p>堆顶元素是二叉树的根节点,即列表首元素。如果我们直接从列表中删除首元素,那么二叉树中所有节点的索引都会发生变化,这将使得后续使用堆化修复变得困难。为了尽量减少元素索引的变动,我们采取以下操作步骤。</p>
|
||||
<ol>
|
||||
<li>交换堆顶元素与堆底元素(即交换根节点与最右叶节点)。</li>
|
||||
<li>交换完成后,将堆底从列表中删除(注意,由于已经交换,实际上删除的是原来的堆顶元素)。</li>
|
||||
|
@ -3431,7 +3431,7 @@
|
||||
<ul>
|
||||
<li>堆是一棵完全二叉树,根据成立条件可分为大顶堆和小顶堆。大(小)顶堆的堆顶元素是最大(小)的。</li>
|
||||
<li>优先队列的定义是具有出队优先级的队列,通常使用堆来实现。</li>
|
||||
<li>堆的常用操作及其对应的时间复杂度包括:元素入堆 <span class="arithmatex">\(O(\log n)\)</span> 、堆顶元素出堆 <span class="arithmatex">\(O(\log n)\)</span> 和访问堆顶元素 <span class="arithmatex">\(O(1)\)</span> 等。</li>
|
||||
<li>堆的常用操作及其对应的时间复杂度包括:元素入堆 <span class="arithmatex">\(O(\log n)\)</span>、堆顶元素出堆 <span class="arithmatex">\(O(\log n)\)</span> 和访问堆顶元素 <span class="arithmatex">\(O(1)\)</span> 等。</li>
|
||||
<li>完全二叉树非常适合用数组表示,因此我们通常使用数组来存储堆。</li>
|
||||
<li>堆化操作用于维护堆的性质,在入堆和出堆操作中都会用到。</li>
|
||||
<li>输入 <span class="arithmatex">\(n\)</span> 个元素并建堆的时间复杂度可以优化至 <span class="arithmatex">\(O(n)\)</span> ,非常高效。</li>
|
||||
|
@ -3462,7 +3462,7 @@
|
||||
</div>
|
||||
<p>对于该问题,我们先介绍两种思路比较直接的解法,再介绍效率更高的堆解法。</p>
|
||||
<h2 id="831">8.3.1 方法一:遍历选择<a class="headerlink" href="#831" title="Permanent link">¶</a></h2>
|
||||
<p>我们可以进行图 8-6 所示的 <span class="arithmatex">\(k\)</span> 轮遍历,分别在每轮中提取第 <span class="arithmatex">\(1\)</span> , <span class="arithmatex">\(2\)</span> , <span class="arithmatex">\(\dots\)</span> , <span class="arithmatex">\(k\)</span> 大的元素,时间复杂度为 <span class="arithmatex">\(O(nk)\)</span> 。</p>
|
||||
<p>我们可以进行图 8-6 所示的 <span class="arithmatex">\(k\)</span> 轮遍历,分别在每轮中提取第 <span class="arithmatex">\(1\)</span>、<span class="arithmatex">\(2\)</span>、<span class="arithmatex">\(\dots\)</span>、<span class="arithmatex">\(k\)</span> 大的元素,时间复杂度为 <span class="arithmatex">\(O(nk)\)</span> 。</p>
|
||||
<p>此方法只适用于 <span class="arithmatex">\(k \ll n\)</span> 的情况,因为当 <span class="arithmatex">\(k\)</span> 与 <span class="arithmatex">\(n\)</span> 比较接近时,其时间复杂度趋向于 <span class="arithmatex">\(O(n^2)\)</span> ,非常耗时。</p>
|
||||
<p><img alt="遍历寻找最大的 k 个元素" src="../top_k.assets/top_k_traversal.png" /></p>
|
||||
<p align="center"> 图 8-6 遍历寻找最大的 k 个元素 </p>
|
||||
|
Reference in New Issue
Block a user