gh-pages
krahets 2 years ago
parent b2e68ade25
commit 6ff9c19dfe

@ -514,10 +514,41 @@
<label class="md-nav__link md-nav__link--active" for="__toc">
2.4. &nbsp; 小结
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
2.4. &nbsp; 小结
</a>
<nav class="md-nav md-nav--secondary" aria-label="目录">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
目录
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#241-q-a" class="md-nav__link">
2.4.1. &nbsp; Q &amp; A
</a>
</li>
</ul>
</nav>
</li>
@ -1809,6 +1840,21 @@
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
目录
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#241-q-a" class="md-nav__link">
2.4.1. &nbsp; Q &amp; A
</a>
</li>
</ul>
</nav>
</div>
</div>
@ -1853,6 +1899,22 @@
<li>我们通常只关注最差空间复杂度,即统计算法在最差输入数据和最差运行时间点下的空间复杂度。</li>
<li>常见空间复杂度从小到大排列有 <span class="arithmatex">\(O(1)\)</span> , <span class="arithmatex">\(O(\log n)\)</span> , <span class="arithmatex">\(O(n)\)</span> , <span class="arithmatex">\(O(n^2)\)</span> , <span class="arithmatex">\(O(2^n)\)</span> 等。</li>
</ul>
<h2 id="241-q-a">2.4.1. &nbsp; Q &amp; A<a class="headerlink" href="#241-q-a" title="Permanent link">&para;</a></h2>
<div class="admonition question">
<p class="admonition-title">尾递归的空间复杂度是 <span class="arithmatex">\(O(1)\)</span> 吗?</p>
<p>理论上,尾递归函数的空间复杂度可以被优化至 <span class="arithmatex">\(O(1)\)</span> 。不过绝大多数编程语言(例如 Java, Python, C++, Go, C# 等)
都不支持自动优化尾递归,因此一般来说空间复杂度是 <span class="arithmatex">\(O(n)\)</span></p>
</div>
<div class="admonition question">
<p class="admonition-title">函数和方法这两个术语的区别是什么?</p>
<p>函数function可以独立被执行所有参数都以显式传递。
方法method与一个对象关联方法被隐式传递给调用它的对象方法能够对类的实例中包含的数据进行操作。</p>
</div>
<div class="admonition question">
<p class="admonition-title">图片“空间复杂度的常见类型”反映的是否是占用空间的绝对大小?</p>
<p>不是,该图片展示的是空间复杂度(即增长趋势),而不是占用空间的绝对大小。每个曲线都包含一个常数项,用来把所有曲线的取值范围压缩到一个视觉舒适的范围内。
实际中,因为我们通常不知道每个方法的“常数项”复杂度是多少,所以一般无法仅凭复杂度来选择 $n = 8 之下的最优解法;但相对地 <span class="arithmatex">\(n = 8^5\)</span> 就很好选了,这是复杂度占主导的情况。</p>
</div>

@ -658,35 +658,8 @@
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#351" class="md-nav__link">
3.5.1. &nbsp; 知识回顾
</a>
<nav class="md-nav" aria-label="3.5.1. &nbsp; 知识回顾">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#_1" class="md-nav__link">
数据结构分类
</a>
</li>
<li class="md-nav__item">
<a href="#_2" class="md-nav__link">
数据类型与编码
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#352-q-a" class="md-nav__link">
3.5.2. &nbsp; Q &amp; A
<a href="#351-q-a" class="md-nav__link">
3.5.1. &nbsp; Q &amp; A
</a>
</li>
@ -1874,35 +1847,8 @@
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#351" class="md-nav__link">
3.5.1. &nbsp; 知识回顾
</a>
<nav class="md-nav" aria-label="3.5.1. &nbsp; 知识回顾">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#_1" class="md-nav__link">
数据结构分类
</a>
</li>
<li class="md-nav__item">
<a href="#_2" class="md-nav__link">
数据类型与编码
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#352-q-a" class="md-nav__link">
3.5.2. &nbsp; Q &amp; A
<a href="#351-q-a" class="md-nav__link">
3.5.1. &nbsp; Q &amp; A
</a>
</li>
@ -1931,15 +1877,14 @@
<h1 id="35">3.5. &nbsp; 小结<a class="headerlink" href="#35" title="Permanent link">&para;</a></h1>
<h2 id="351">3.5.1. &nbsp; 知识回顾<a class="headerlink" href="#351" title="Permanent link">&para;</a></h2>
<h3 id="_1">数据结构分类<a class="headerlink" href="#_1" title="Permanent link">&para;</a></h3>
<p><strong>数据结构分类</strong></p>
<ul>
<li>数据结构可以从逻辑结构和物理结构两个角度进行分类。逻辑结构描述了数据元素之间的逻辑关系,而物理结构描述了数据在计算机内存中的存储方式。</li>
<li>常见的逻辑结构包括线性、树状和网状等。通常我们根据逻辑结构将数据结构分为线性(数组、链表、栈、队列)和非线性(树、图、堆)两种。哈希表的实现可能同时包含线性和非线性结构。</li>
<li>当程序运行时,数据被存储在计算机内存中。每个内存空间都拥有对应的内存地址,程序通过这些内存地址访问数据。</li>
<li>物理结构主要分为连续空间存储(数组)和离散空间存储(链表)。所有数据结构都是由数组、链表或两者的组合实现的。</li>
</ul>
<h3 id="_2">数据类型与编码<a class="headerlink" href="#_2" title="Permanent link">&para;</a></h3>
<p><strong>数据类型与编码</strong></p>
<ul>
<li>计算机中的基本数据类型包括整数 byte, short, int, long 、浮点数 float, double 、字符 char 和布尔 boolean 。它们的取值范围取决于占用空间大小和表示方式。</li>
<li>原码、反码和补码是在计算机中编码数字的三种方法,它们之间是可以相互转换的。整数的原码的最高位是符号位,其余位是数字的值。</li>
@ -1948,7 +1893,7 @@
<li>ASCII 码是最早出现的英文字符集,长度为 1 字节,共收录 127 个字符。GBK 字符集是常用的中文字符集共收录两万多个汉字。Unicode 致力于提供一个完整的字符集标准,收录世界内各种语言的字符,从而解决由于字符编码方法不一致而导致的乱码问题。</li>
<li>UTF-8 是最受欢迎的 Unicode 编码方法通用性非常好。它是一种变长的编码方法具有很好的扩展性有效提升了存储空间的使用效率。UTF-16 和 UTF-32 是等长的编码方法。在编码中文时UTF-16 比 UTF-8 的占用空间更小。Java, C# 等编程语言默认使用 UTF-16 编码。</li>
</ul>
<h2 id="352-q-a">3.5.2. &nbsp; Q &amp; A<a class="headerlink" href="#352-q-a" title="Permanent link">&para;</a></h2>
<h2 id="351-q-a">3.5.1. &nbsp; Q &amp; A<a class="headerlink" href="#351-q-a" title="Permanent link">&para;</a></h2>
<div class="admonition question">
<p class="admonition-title">为什么哈希表同时包含线性数据结构和非线性数据结构?</p>
<p>哈希表底层是数组,而为了解决哈希冲突,我们可能会使用“拉链法”(后续散列表章节会讲)。在拉链法中,数组中每个地址(桶)指向一个链表;当这个链表长度超过一定阈值时,又可能被转化为树(通常为红黑树)。因此,哈希表可能同时包含线性(数组、链表)和非线性(树)数据结构。</p>

@ -1251,10 +1251,41 @@
<label class="md-nav__link md-nav__link--active" for="__toc">
9.4. &nbsp; 小结
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
9.4. &nbsp; 小结
</a>
<nav class="md-nav md-nav--secondary" aria-label="目录">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
目录
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#941-q-a" class="md-nav__link">
9.4.1. &nbsp; Q &amp; A
</a>
</li>
</ul>
</nav>
</li>
@ -1809,6 +1840,21 @@
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
目录
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#941-q-a" class="md-nav__link">
9.4.1. &nbsp; Q &amp; A
</a>
</li>
</ul>
</nav>
</div>
</div>
@ -1844,6 +1890,20 @@
<li>图的广度优先遍历是一种由近及远、层层扩张的搜索方式,通常借助队列实现。</li>
<li>图的深度优先遍历是一种优先走到底、无路可走时再回溯的搜索方式,常基于递归来实现。</li>
</ul>
<h2 id="941-q-a">9.4.1. &nbsp; Q &amp; A<a class="headerlink" href="#941-q-a" title="Permanent link">&para;</a></h2>
<div class="admonition question">
<p class="admonition-title">路径的定义是顶点序列还是边序列?</p>
<p>维基百科上不同语言版本的定义不一致英文版是“路径是一个边序列”而中文版是“路径是一个顶点序列”。以下是英文版原文In graph theory, a path in a graph is a finite or infinite sequence of edges which joins a sequence of vertices.
在本文中,路径被认为是一个边序列,而不是一个顶点序列。这是因为两个顶点之间可能存在多条边连接,此时每条边都对应一条路径。</p>
</div>
<div class="admonition question">
<p class="admonition-title">非连通图中,是否会有无法遍历到的点?</p>
<p>在非连通图中,从某个顶点出发,至少有一个顶点无法到达。遍历非连通图需要设置多个起点,以遍历到图的所有连通分量。</p>
</div>
<div class="admonition question">
<p class="admonition-title">在邻接表中,“与该顶点相连的所有顶点”的顶点顺序是否有要求?</p>
<p>可以是任意顺序。但在实际应用中,可能会需要按照指定规则来排序,比如按照顶点添加的次序、或者按照顶点值大小的顺序等等,这样可以有助于快速查找“带有某种极值”的顶点。</p>
</div>

@ -3248,7 +3248,7 @@
<h2 id="813">8.1.3. &nbsp; 堆常见应用<a class="headerlink" href="#813" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>优先队列</strong>:堆通常作为实现优先队列的首选数据结构,其入队和出队操作的时间复杂度均为 <span class="arithmatex">\(O(\log n)\)</span> ,而建队操作为 <span class="arithmatex">\(O(n)\)</span> ,这些操作都非常高效。</li>
<li><strong>堆排序</strong>:给定一组数据,我们可以用它们建立一个堆,然后依次将所有元素弹出,从而得到一个有序序列。当然,堆排序的实现方法并不需要弹出元素,而是每轮将堆顶元素交换至数组尾部并缩小堆的长度</li>
<li><strong>堆排序</strong>:给定一组数据,我们可以用它们建立一个堆,然后不断地执行元素出堆操作,从而得到有序数据。当然,堆排序还有一种更优雅的实现,详见后续的堆排序章节</li>
<li><strong>获取最大的 <span class="arithmatex">\(k\)</span> 个元素</strong>:这是一个经典的算法问题,同时也是一种典型应用,例如选择热度前 10 的新闻作为微博热搜,选取销量前 10 的商品等。</li>
</ul>

@ -1933,7 +1933,7 @@
</div>
</div>
<h2 id="1131">11.3.1. &nbsp; 算法流程<a class="headerlink" href="#1131" title="Permanent link">&para;</a></h2>
<p>输入数组长度为 <span class="arithmatex">\(n\)</span> ,冒泡排序的步骤为:</p>
<p>设数组长度为 <span class="arithmatex">\(n\)</span> ,冒泡排序的步骤为:</p>
<ol>
<li>首先,对 <span class="arithmatex">\(n\)</span> 个元素执行“冒泡”,<strong>将数组的最大元素交换至正确位置</strong></li>
<li>接下来,对剩余 <span class="arithmatex">\(n - 1\)</span> 个元素执行“冒泡”,<strong>将第二大元素交换至正确位置</strong></li>

@ -1878,7 +1878,7 @@
<h1 id="112">11.2. &nbsp; 选择排序<a class="headerlink" href="#112" title="Permanent link">&para;</a></h1>
<p>「选择排序 Selection Sort」的工作原理非常直接开启一个循环每轮从未排序区间选择最小的元素将其放到已排序区间的末尾。</p>
<p>选择排序的算法流程如下:</p>
<p>设数组的长度为 <span class="arithmatex">\(n\)</span> 选择排序的算法流程如下:</p>
<ol>
<li>初始状态下,所有元素未排序,即未排序(索引)区间为 <span class="arithmatex">\([0, n-1]\)</span></li>
<li>选取区间 <span class="arithmatex">\([0, n-1]\)</span> 中的最小元素,将其与索引 <span class="arithmatex">\(0\)</span> 处元素交换。完成后,数组前 1 个元素已排序。</li>

File diff suppressed because one or more lines are too long

Binary file not shown.
Loading…
Cancel
Save