This commit is contained in:
krahets
2023-08-19 19:21:30 +08:00
parent 5884de5246
commit c2642f951c
25 changed files with 163 additions and 110 deletions

View File

@ -3452,6 +3452,15 @@
<p>假如把列表元素换成链表节点 <code>n = [n1, n2, n3, n4, n5]</code> ,通常情况下这五个节点对象也是被分散存储在内存各处的。然而,给定一个列表索引,我们仍然可以在 <span class="arithmatex">\(O(1)\)</span> 时间内获取到节点内存地址,从而访问到对应的节点。这是因为数组中存储的是节点的引用,而非节点本身。</p>
<p>与许多语言不同的是,在 Python 中数字也被包装为对象,列表中存储的不是数字本身,而是对数字的引用。因此,我们会发现两个数组中的相同数字拥有同一个 id ,并且这些数字的内存地址是无需连续的。</p>
</div>
<div class="admonition question">
<p class="admonition-title">C++ STL 里面的 std::list 已经实现了双向链表,但好像一些算法的书上都不怎么直接用这个,是不是有什么局限性呢?</p>
<p>一方面,我们往往更青睐使用数组实现算法,而只有在必要时才使用链表。这是因为:</p>
<ol>
<li>空间开销:由于每个元素需要两个额外的指针(一个用于前一个元素,一个用于后一个元素),所以 <code>std::list</code> 通常比 <code>std::vector</code> 更占用空间。</li>
<li>缓存不友好:由于数据不是连续存放的,<code>std::list</code> 对缓存的利用率较低。一般情况下,<code>std::vector</code> 的性能会更好。</li>
</ol>
<p>另一方面,必要使用链表的情况主要是二叉树和图。栈和队列往往会使用编程语言提供的 <code>stack</code><code>queue</code> ,而非链表。</p>
</div>