mirror of
https://github.com/krahets/hello-algo.git
synced 2025-07-10 08:50:20 +08:00
deploy
This commit is contained in:
@ -1601,9 +1601,7 @@
|
||||
|
||||
<h1 id="41">4.1. 数组<a class="headerlink" href="#41" title="Permanent link">¶</a></h1>
|
||||
<p>「数组 Array」是一种将 <strong>相同类型元素</strong> 存储在 <strong>连续内存空间</strong> 的数据结构,将元素在数组中的位置称为元素的「索引 Index」。</p>
|
||||
<p><img alt="array_definition" src="../array.assets/array_definition.png" /></p>
|
||||
<p align="center"> Fig. 数组定义与存储方式 </p>
|
||||
|
||||
<p><img alt="数组定义与存储方式" src="../array.assets/array_definition.png" /></p>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">Note</p>
|
||||
<p>观察上图,我们发现 <strong>数组首元素的索引为 <span class="arithmatex">\(0\)</span></strong> 。你可能会想,这并不符合日常习惯,首个元素的索引为什么不是 <span class="arithmatex">\(1\)</span> 呢,这不是更加自然吗?我认同你的想法,但请先记住这个设定,后面讲内存地址计算时,我会尝试解答这个问题。</p>
|
||||
@ -1681,9 +1679,7 @@
|
||||
</div>
|
||||
<h2 id="411">4.1.1. 数组优点<a class="headerlink" href="#411" title="Permanent link">¶</a></h2>
|
||||
<p><strong>在数组中访问元素非常高效</strong>。这是因为在数组中,计算元素的内存地址非常容易。给定数组首个元素的地址、和一个元素的索引,利用以下公式可以直接计算得到该元素的内存地址,从而直接访问此元素。</p>
|
||||
<p><img alt="array_memory_location_calculation" src="../array.assets/array_memory_location_calculation.png" /></p>
|
||||
<p align="center"> Fig. 数组元素的内存地址计算 </p>
|
||||
|
||||
<p><img alt="数组元素的内存地址计算" src="../array.assets/array_memory_location_calculation.png" /></p>
|
||||
<div class="highlight"><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="c1"># 元素内存地址 = 数组内存地址 + 元素长度 * 元素索引</span>
|
||||
<a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a><span class="nv">elementAddr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>firtstElementAddr<span class="w"> </span>+<span class="w"> </span>elementLength<span class="w"> </span>*<span class="w"> </span>elementIndex
|
||||
</code></pre></div>
|
||||
@ -1942,7 +1938,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<p><strong>数组中插入或删除元素效率低下</strong>。如果我们想要在数组中间插入一个元素,由于数组元素在内存中是“紧挨着的”,它们之间没有空间再放任何数据。因此,我们不得不将此索引之后的所有元素都向后移动一位,然后再把元素赋值给该索引。</p>
|
||||
<p><img alt="array_insert_element" src="../array.assets/array_insert_element.png" /></p>
|
||||
<p><img alt="数组插入元素" src="../array.assets/array_insert_element.png" /></p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="4:9"><input checked="checked" id="__tabbed_4_1" name="__tabbed_4" type="radio" /><input id="__tabbed_4_2" name="__tabbed_4" type="radio" /><input id="__tabbed_4_3" name="__tabbed_4" type="radio" /><input id="__tabbed_4_4" name="__tabbed_4" type="radio" /><input id="__tabbed_4_5" name="__tabbed_4" type="radio" /><input id="__tabbed_4_6" name="__tabbed_4" type="radio" /><input id="__tabbed_4_7" name="__tabbed_4" type="radio" /><input id="__tabbed_4_8" name="__tabbed_4" type="radio" /><input id="__tabbed_4_9" name="__tabbed_4" type="radio" /><div class="tabbed-labels"><label for="__tabbed_4_1">Java</label><label for="__tabbed_4_2">C++</label><label for="__tabbed_4_3">Python</label><label for="__tabbed_4_4">Go</label><label for="__tabbed_4_5">JavaScript</label><label for="__tabbed_4_6">TypeScript</label><label for="__tabbed_4_7">C</label><label for="__tabbed_4_8">C#</label><label for="__tabbed_4_9">Swift</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@ -2048,7 +2044,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<p>删除元素也是类似,如果我们想要删除索引 <span class="arithmatex">\(i\)</span> 处的元素,则需要把索引 <span class="arithmatex">\(i\)</span> 之后的元素都向前移动一位。值得注意的是,删除元素后,原先末尾的元素变得“无意义”了,我们无需特意去修改它。</p>
|
||||
<p><img alt="array_remove_element" src="../array.assets/array_remove_element.png" /></p>
|
||||
<p><img alt="数组删除元素" src="../array.assets/array_remove_element.png" /></p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="5:10"><input checked="checked" id="__tabbed_5_1" name="__tabbed_5" type="radio" /><input id="__tabbed_5_2" name="__tabbed_5" type="radio" /><input id="__tabbed_5_3" name="__tabbed_5" type="radio" /><input id="__tabbed_5_4" name="__tabbed_5" type="radio" /><input id="__tabbed_5_5" name="__tabbed_5" type="radio" /><input id="__tabbed_5_6" name="__tabbed_5" type="radio" /><input id="__tabbed_5_7" name="__tabbed_5" type="radio" /><input id="__tabbed_5_8" name="__tabbed_5" type="radio" /><input id="__tabbed_5_9" name="__tabbed_5" type="radio" /><input id="__tabbed_5_10" name="__tabbed_5" type="radio" /><div class="tabbed-labels"><label for="__tabbed_5_1">Java</label><label for="__tabbed_5_2">C++</label><label for="__tabbed_5_3">Python</label><label for="__tabbed_5_4">Go</label><label for="__tabbed_5_5">JavaScript</label><label for="__tabbed_5_6">TypeScript</label><label for="__tabbed_5_7">C</label><label for="__tabbed_5_8">C#</label><label for="__tabbed_5_9">Swift</label><label for="__tabbed_5_10">Zig</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
|
@ -1606,9 +1606,7 @@
|
||||
</div>
|
||||
<p>「链表 Linked List」是一种线性数据结构,其中每个元素都是单独的对象,各个元素(一般称为结点)之间通过指针连接。由于结点中记录了连接关系,因此链表的存储方式相比于数组更加灵活,系统不必保证内存地址的连续性。</p>
|
||||
<p>链表的「结点 Node」包含两项数据,一是结点「值 Value」,二是指向下一结点的「指针 Pointer」(或称「引用 Reference」)。</p>
|
||||
<p><img alt="linkedlist_definition" src="../linked_list.assets/linkedlist_definition.png" /></p>
|
||||
<p align="center"> Fig. 链表定义与存储方式 </p>
|
||||
|
||||
<p><img alt="链表定义与存储方式" src="../linked_list.assets/linkedlist_definition.png" /></p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="1:10"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><input id="__tabbed_1_6" name="__tabbed_1" type="radio" /><input id="__tabbed_1_7" name="__tabbed_1" type="radio" /><input id="__tabbed_1_8" name="__tabbed_1" type="radio" /><input id="__tabbed_1_9" name="__tabbed_1" type="radio" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Java</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Python</label><label for="__tabbed_1_4">Go</label><label for="__tabbed_1_5">JavaScript</label><label for="__tabbed_1_6">TypeScript</label><label for="__tabbed_1_7">C</label><label for="__tabbed_1_8">C#</label><label for="__tabbed_1_9">Swift</label><label for="__tabbed_1_10">Zig</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@ -1875,7 +1873,7 @@
|
||||
</div>
|
||||
<h2 id="421">4.2.1. 链表优点<a class="headerlink" href="#421" title="Permanent link">¶</a></h2>
|
||||
<p><strong>在链表中,插入与删除结点的操作效率高</strong>。比如,如果我们想在链表中间的两个结点 <code>A</code> , <code>B</code> 之间插入一个新结点 <code>P</code> ,我们只需要改变两个结点指针即可,时间复杂度为 <span class="arithmatex">\(O(1)\)</span> ,相比数组的插入操作高效很多。</p>
|
||||
<p><img alt="linkedlist_insert_node" src="../linked_list.assets/linkedlist_insert_node.png" /></p>
|
||||
<p><img alt="链表插入结点" src="../linked_list.assets/linkedlist_insert_node.png" /></p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="3:10"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><input id="__tabbed_3_3" name="__tabbed_3" type="radio" /><input id="__tabbed_3_4" name="__tabbed_3" type="radio" /><input id="__tabbed_3_5" name="__tabbed_3" type="radio" /><input id="__tabbed_3_6" name="__tabbed_3" type="radio" /><input id="__tabbed_3_7" name="__tabbed_3" type="radio" /><input id="__tabbed_3_8" name="__tabbed_3" type="radio" /><input id="__tabbed_3_9" name="__tabbed_3" type="radio" /><input id="__tabbed_3_10" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">Java</label><label for="__tabbed_3_2">C++</label><label for="__tabbed_3_3">Python</label><label for="__tabbed_3_4">Go</label><label for="__tabbed_3_5">JavaScript</label><label for="__tabbed_3_6">TypeScript</label><label for="__tabbed_3_7">C</label><label for="__tabbed_3_8">C#</label><label for="__tabbed_3_9">Swift</label><label for="__tabbed_3_10">Zig</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@ -1966,7 +1964,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<p>在链表中删除结点也很方便,只需要改变一个结点指针即可。如下图所示,虽然在完成删除后结点 <code>P</code> 仍然指向 <code>n2</code> ,但实际上 <code>P</code> 已经不属于此链表了,因为遍历此链表是无法访问到 <code>P</code> 的。</p>
|
||||
<p><img alt="linkedlist_remove_node" src="../linked_list.assets/linkedlist_remove_node.png" /></p>
|
||||
<p><img alt="链表删除结点" src="../linked_list.assets/linkedlist_remove_node.png" /></p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="4:10"><input checked="checked" id="__tabbed_4_1" name="__tabbed_4" type="radio" /><input id="__tabbed_4_2" name="__tabbed_4" type="radio" /><input id="__tabbed_4_3" name="__tabbed_4" type="radio" /><input id="__tabbed_4_4" name="__tabbed_4" type="radio" /><input id="__tabbed_4_5" name="__tabbed_4" type="radio" /><input id="__tabbed_4_6" name="__tabbed_4" type="radio" /><input id="__tabbed_4_7" name="__tabbed_4" type="radio" /><input id="__tabbed_4_8" name="__tabbed_4" type="radio" /><input id="__tabbed_4_9" name="__tabbed_4" type="radio" /><input id="__tabbed_4_10" name="__tabbed_4" type="radio" /><div class="tabbed-labels"><label for="__tabbed_4_1">Java</label><label for="__tabbed_4_2">C++</label><label for="__tabbed_4_3">Python</label><label for="__tabbed_4_4">Go</label><label for="__tabbed_4_5">JavaScript</label><label for="__tabbed_4_6">TypeScript</label><label for="__tabbed_4_7">C</label><label for="__tabbed_4_8">C#</label><label for="__tabbed_4_9">Swift</label><label for="__tabbed_4_10">Zig</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@ -2484,7 +2482,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p><img alt="linkedlist_common_types" src="../linked_list.assets/linkedlist_common_types.png" /></p>
|
||||
<p><img alt="常见链表种类" src="../linked_list.assets/linkedlist_common_types.png" /></p>
|
||||
<p align="center"> Fig. 常见链表类型 </p>
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user