This commit is contained in:
krahets
2024-01-12 21:14:29 +08:00
parent 2979889781
commit 6dc2b9eabe
21 changed files with 73 additions and 103 deletions

View File

@@ -3520,8 +3520,8 @@
<li>数组和链表是两种基本的数据结构,分别代表数据在计算机内存中的两种存储方式:连续空间存储和分散空间存储。两者的特点呈现出互补的特性。</li>
<li>数组支持随机访问、占用内存较少;但插入和删除元素效率低,且初始化后长度不可变。</li>
<li>链表通过更改引用(指针)实现高效的节点插入与删除,且可以灵活调整长度;但节点访问效率低、占用内存较多。常见的链表类型包括单向链表、环形链表、双向链表。</li>
<li>列表是一种支持增删查改的元素有序集合,通常基于动态数组实现它保留了数组的优势,同时可以灵活调整长度。</li>
<li>列表的出现大幅提高了数组的实用性,但可能导致部分内存空间浪费。</li>
<li>列表是一种支持增删查改的元素有序集合,通常基于动态数组实现它保留了数组的优势,同时可以灵活调整长度。</li>
<li>列表的出现大幅提高了数组的实用性,但可能导致部分内存空间浪费。</li>
<li>程序运行时,数据主要存储在内存中。数组可提供更高的内存空间效率,而链表则在内存使用上更加灵活。</li>
<li>缓存通过缓存行、预取机制以及空间局部性和时间局部性等数据加载机制,为 CPU 提供快速数据访问,显著提升程序的执行效率。</li>
<li>由于数组具有更高的缓存命中率,因此它通常比链表更高效。在选择数据结构时,应根据具体需求和场景做出恰当选择。</li>
@@ -3534,10 +3534,10 @@
<li>大小限制:栈内存相对较小,堆的大小一般受限于可用内存。因此堆更加适合存储大型数组。</li>
<li>灵活性:栈上的数组的大小需要在编译时确定,而堆上的数组的大小可以在运行时动态确定。</li>
</ol>
<p><strong>Q</strong>:为什么数组要求相同类型的元素,而在链表中却没有强调同类型呢?</p>
<p><strong>Q</strong>:为什么数组要求相同类型的元素,而在链表中却没有强调同类型呢?</p>
<p>链表由节点组成,节点之间通过引用(指针)连接,各个节点可以存储不同类型的数据,例如 <code>int</code><code>double</code><code>string</code><code>object</code> 等。</p>
<p>相对地,数组元素则必须是相同类型的,这样才能通过计算偏移量来获取对应元素位置。例如,数组同时包含 <code>int</code><code>long</code> 两种类型,单个元素分别占用 4 字节 和 8 字节 ,此时就不能用以下公式计算偏移量了,因为数组中包含了两种“元素长度”。</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="c1"># 元素内存地址 = 数组内存地址 + 元素长度 * 元素索引</span>
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="c1"># 元素内存地址 = 数组内存地址(首元素内存地址) + 元素长度 * 元素索引</span>
</code></pre></div>
<p><strong>Q</strong>:删除节点后,是否需要把 <code>P.next</code> 设为 <code>None</code> 呢?</p>
<p>不修改 <code>P.next</code> 也可以。从该链表的角度看,从头节点遍历到尾节点已经不会遇到 <code>P</code> 了。这意味着节点 <code>P</code> 已经从链表中删除了,此时节点 <code>P</code> 指向哪里都不会对该链表产生影响。</p>