This commit is contained in:
krahets
2023-08-20 14:52:42 +08:00
parent 96fded547b
commit 26a2e7f171
42 changed files with 234 additions and 230 deletions
@@ -3926,7 +3926,7 @@
</div>
<h3 id="4">4. &nbsp; 删除元素<a class="headerlink" href="#4" title="Permanent link">&para;</a></h3>
<p>同理,如果我们想要删除索引 <span class="arithmatex">\(i\)</span> 处的元素,则需要把索引 <span class="arithmatex">\(i\)</span> 之后的元素都向前移动一位。</p>
<p>请注意,删除元素完成后,原先末尾的元素变得“无意义”了,所以我们无特意去修改它。</p>
<p>请注意,删除元素完成后,原先末尾的元素变得“无意义”了,所以我们无特意去修改它。</p>
<p><img alt="数组删除元素" src="../array.assets/array_remove_element.png" /></p>
<p align="center"> 图:数组删除元素 </p>
@@ -4571,7 +4571,7 @@
<h2 id="412">4.1.2 &nbsp; 数组优点与局限性<a class="headerlink" href="#412" title="Permanent link">&para;</a></h2>
<p>数组存储在连续的内存空间内,且元素类型相同。这包含丰富的先验信息,系统可以利用这些信息来优化操作和运行效率,包括:</p>
<ul>
<li><strong>空间效率高</strong>: 数组为数据分配了连续的内存块,无额外的结构开销。</li>
<li><strong>空间效率高</strong>: 数组为数据分配了连续的内存块,无额外的结构开销。</li>
<li><strong>支持随机访问</strong>: 数组允许在 <span class="arithmatex">\(O(1)\)</span> 时间内访问任何元素。</li>
<li><strong>缓存局部性</strong>: 当访问数组元素时,计算机不仅会加载它,还会缓存其周围的其他数据,从而借助高速缓存来提升后续操作的执行速度。</li>
</ul>
@@ -3523,7 +3523,7 @@
<h1 id="42">4.2 &nbsp; 链表<a class="headerlink" href="#42" title="Permanent link">&para;</a></h1>
<p>内存空间是所有程序的公共资源,在一个复杂的系统运行环境下,空闲的内存空间可能散落在内存各处。我们知道,存储数组的内存空间必须是连续的,而当数组非常大时,内存可能无法提供如此大的连续空间。此时链表的灵活性优势就体现出来了。</p>
<p>「链表 Linked List」是一种线性数据结构,其中的每个元素都是一个节点对象,各个节点通过“引用”相连接。引用记录了下一个节点的内存地址,我们可以通过它从当前节点访问到下一个节点。这意味着链表的各个节点可以被分散存储在内存各处,它们的内存地址是无连续的。</p>
<p>「链表 Linked List」是一种线性数据结构,其中的每个元素都是一个节点对象,各个节点通过“引用”相连接。引用记录了下一个节点的内存地址,我们可以通过它从当前节点访问到下一个节点。这意味着链表的各个节点可以被分散存储在内存各处,它们的内存地址是无连续的。</p>
<p><img alt="链表定义与存储方式" src="../linked_list.assets/linkedlist_definition.png" /></p>
<p align="center"> 图:链表定义与存储方式 </p>
+1 -1
View File
@@ -3509,7 +3509,7 @@
<h1 id="43">4.3 &nbsp; 列表<a class="headerlink" href="#43" title="Permanent link">&para;</a></h1>
<p><strong>数组长度不可变导致实用性降低</strong>。在实际中,我们可能事先无法确定需要存储多少数据,这使数组长度的选择变得困难。若长度过小,需要在持续添加数据时频繁扩容数组;若长度过大,则会造成内存空间的浪费。</p>
<p>为解决此问题,出现了一种被称为「动态数组 Dynamic Array」的数据结构,即长度可变的数组,也常被称为「列表 List」。列表基于数组实现,继承了数组的优点,并且可以在程序运行过程中动态扩容。我们可以在列表中自由地添加元素,而无担心超过容量限制。</p>
<p>为解决此问题,出现了一种被称为「动态数组 Dynamic Array」的数据结构,即长度可变的数组,也常被称为「列表 List」。列表基于数组实现,继承了数组的优点,并且可以在程序运行过程中动态扩容。我们可以在列表中自由地添加元素,而无担心超过容量限制。</p>
<h2 id="431">4.3.1 &nbsp; 列表常用操作<a class="headerlink" href="#431" title="Permanent link">&para;</a></h2>
<h3 id="1">1. &nbsp; 初始化列表<a class="headerlink" href="#1" title="Permanent link">&para;</a></h3>
<p>我们通常使用“无初始值”和“有初始值”这两种初始化方法。</p>
@@ -3450,7 +3450,7 @@
<div class="admonition question">
<p class="admonition-title">在 Python 中初始化 <code>n = [1, 2, 3]</code> 后,这 3 个元素的地址是相连的,但是初始化 <code>m = [2, 1, 3]</code> 会发现它们每个元素的 id 并不是连续的,而是分别跟 <code>n</code> 中的相同。这些元素地址不连续,那么 <code>m</code> 还是数组吗?</p>
<p>假如把列表元素换成链表节点 <code>n = [n1, n2, n3, n4, n5]</code> ,通常情况下这五个节点对象也是被分散存储在内存各处的。然而,给定一个列表索引,我们仍然可以在 <span class="arithmatex">\(O(1)\)</span> 时间内获取到节点内存地址,从而访问到对应的节点。这是因为数组中存储的是节点的引用,而非节点本身。</p>
<p>与许多语言不同的是,在 Python 中数字也被包装为对象,列表中存储的不是数字本身,而是对数字的引用。因此,我们会发现两个数组中的相同数字拥有同一个 id ,并且这些数字的内存地址是无连续的。</p>
<p>与许多语言不同的是,在 Python 中数字也被包装为对象,列表中存储的不是数字本身,而是对数字的引用。因此,我们会发现两个数组中的相同数字拥有同一个 id ,并且这些数字的内存地址是无连续的。</p>
</div>
<div class="admonition question">
<p class="admonition-title">C++ STL 里面的 std::list 已经实现了双向链表,但好像一些算法的书上都不怎么直接用这个,是不是有什么局限性呢?</p>