mirror of
https://github.com/krahets/hello-algo.git
synced 2025-07-28 04:42:48 +08:00
deploy
This commit is contained in:
@ -3446,7 +3446,7 @@
|
||||
</div>
|
||||
<div class="admonition question">
|
||||
<p class="admonition-title">为什么数组要求相同类型的元素,而在链表中却没有强调同类型呢?</p>
|
||||
<p>链表由结点组成,结点之间通过引用(指针)连接,各个结点可以存储不同类型的数据,例如 int, double, string, object 等。</p>
|
||||
<p>链表由结点组成,结点之间通过引用(指针)连接,各个结点可以存储不同类型的数据,例如 int、double、string、object 等。</p>
|
||||
<p>相对地,数组元素则必须是相同类型的,这样才能通过计算偏移量来获取对应元素位置。例如,如果数组同时包含 int 和 long 两种类型,单个元素分别占用 4 bytes 和 8 bytes ,那么此时就不能用以下公式计算偏移量了,因为数组中包含了两种 <code>elementLength</code> 。</p>
|
||||
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a>// 元素内存地址 = 数组内存地址 + 元素长度 * 元素索引
|
||||
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||
@ -3455,7 +3455,7 @@
|
||||
<div class="admonition question">
|
||||
<p class="admonition-title">删除节点后,是否需要把 <code>P.next</code> 设为 <span class="arithmatex">\(\text{None}\)</span> 呢?</p>
|
||||
<p>不修改 <code>P.next</code> 也可以。从该链表的角度看,从头结点遍历到尾结点已经遇不到 <code>P</code> 了。这意味着结点 <code>P</code> 已经从链表中删除了,此时结点 <code>P</code> 指向哪里都不会对这条链表产生影响了。</p>
|
||||
<p>从垃圾回收的角度看,对于 Java, Python, Go 等拥有自动垃圾回收的语言来说,节点 <code>P</code> 是否被回收取决于是否有仍存在指向它的引用,而不是 <code>P.next</code> 的值。在 C, C++ 等语言中,我们需要手动释放节点内存。</p>
|
||||
<p>从垃圾回收的角度看,对于 Java、Python、Go 等拥有自动垃圾回收的语言来说,节点 <code>P</code> 是否被回收取决于是否有仍存在指向它的引用,而不是 <code>P.next</code> 的值。在 C 和 C++ 等语言中,我们需要手动释放节点内存。</p>
|
||||
</div>
|
||||
<div class="admonition question">
|
||||
<p class="admonition-title">在链表中插入和删除操作的时间复杂度是 <span class="arithmatex">\(O(1)\)</span> 。但是增删之前都需要 <span class="arithmatex">\(O(n)\)</span> 查找元素,那为什么时间复杂度不是 <span class="arithmatex">\(O(n)\)</span> 呢?</p>
|
||||
@ -3463,9 +3463,9 @@
|
||||
</div>
|
||||
<div class="admonition question">
|
||||
<p class="admonition-title">图片“链表定义与存储方式”中,浅蓝色的存储结点指针是占用一块内存地址吗?还是和结点值各占一半呢?</p>
|
||||
<p>文中只是一个示意图,只是定性表示。定量的话需要根据具体情况分析:</p>
|
||||
<p>文中的示意图只是定性表示,定量表示需要根据具体情况进行分析。</p>
|
||||
<ul>
|
||||
<li>不同类型的结点值占用的空间是不同的,比如 int, long, double, 或者是类的实例等等。</li>
|
||||
<li>不同类型的结点值占用的空间是不同的,比如 int、long、double 和实例对象等。</li>
|
||||
<li>指针变量占用的内存空间大小根据所使用的操作系统及编译环境而定,大多为 8 字节或 4 字节。</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -3484,11 +3484,11 @@
|
||||
</div>
|
||||
<div class="admonition question">
|
||||
<p class="admonition-title">C++ STL 里面的 std::list 已经实现了双向链表,但好像一些算法的书上都不怎么直接用这个,是不是有什么局限性呢?</p>
|
||||
<p>一方面,我们往往更青睐使用数组实现算法,而只有在必要时才使用链表。这是因为:</p>
|
||||
<ol>
|
||||
<p>一方面,我们往往更青睐使用数组实现算法,而只有在必要时才使用链表,主要有两个原因。</p>
|
||||
<ul>
|
||||
<li>空间开销:由于每个元素需要两个额外的指针(一个用于前一个元素,一个用于后一个元素),所以 <code>std::list</code> 通常比 <code>std::vector</code> 更占用空间。</li>
|
||||
<li>缓存不友好:由于数据不是连续存放的,<code>std::list</code> 对缓存的利用率较低。一般情况下,<code>std::vector</code> 的性能会更好。</li>
|
||||
</ol>
|
||||
</ul>
|
||||
<p>另一方面,必要使用链表的情况主要是二叉树和图。栈和队列往往会使用编程语言提供的 <code>stack</code> 和 <code>queue</code> ,而非链表。</p>
|
||||
</div>
|
||||
|
||||
|
Reference in New Issue
Block a user