增加dist静态资源
This commit is contained in:
115
.vitepress/dist/assets/技术资源汇总(杭电支持版)_3.编程思维体系构建_3.4.5.1C语言自测标准——链表.md.DVzk3soj.js
vendored
Normal file
115
.vitepress/dist/assets/技术资源汇总(杭电支持版)_3.编程思维体系构建_3.4.5.1C语言自测标准——链表.md.DVzk3soj.js
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
import{_ as s,c as i,o as a,a4 as n}from"./chunks/framework.DtvhUNIn.js";const c=JSON.parse('{"title":"C 语言自测标准——链表","description":"","frontmatter":{},"headers":[],"relativePath":"技术资源汇总(杭电支持版)/3.编程思维体系构建/3.4.5.1C语言自测标准——链表.md","filePath":"技术资源汇总(杭电支持版)/3.编程思维体系构建/3.4.5.1C语言自测标准——链表.md"}'),h={name:"技术资源汇总(杭电支持版)/3.编程思维体系构建/3.4.5.1C语言自测标准——链表.md"},p=n(`<h1 id="c-语言自测标准——链表" tabindex="-1">C 语言自测标准——链表 <a class="header-anchor" href="#c-语言自测标准——链表" aria-label="Permalink to "C 语言自测标准——链表""></a></h1><h2 id="链表-单链表-是什么" tabindex="-1">链表(单链表)是什么 <a class="header-anchor" href="#链表-单链表-是什么" aria-label="Permalink to "链表(单链表)是什么""></a></h2><p>链表又称单链表、链式存储结构,用于存储逻辑关系为“一对一”的数据。</p><p>使用链表存储数据,不强制要求数据在内存中集中存储,各个元素可以分散存储在内存中。例如,使用链表存储 {1,2,3},各个元素在内存中的存储状态可能是:</p><p><img src="https://cdn.xyxsw.site/boxcnuwZzqX4dF8xKTYajwrDSxf.png" alt=""></p><p>可以看到,数据不仅没有集中存放,在内存中的存储次序也是混乱的。那么,链表是如何存储数据间逻辑关系的呢?</p><p>链表存储数据间逻辑关系的实现方案是:为每一个元素配置一个指针,每个元素的指针都指向自己的直接后继元素,如下图所示:</p><p><img src="https://cdn.xyxsw.site/boxcnAnkVAJmMT0NSNvo6crXYAd.png" alt=""></p><p>显然,我们只需要记住元素 1 的存储位置,通过它的指针就可以找到元素 2,通过元素 2 的指针就可以找到元素 3,以此类推,各个元素的先后次序一目了然。像图 2 这样,数据元素随机存储在内存中,通过指针维系数据之间“一对一”的逻辑关系,这样的存储结构就是链表。</p><h3 id="结点-节点" tabindex="-1">结点(节点) <a class="header-anchor" href="#结点-节点" aria-label="Permalink to "结点(节点)""></a></h3><p>在链表中,每个数据元素都配有一个指针,这意味着,链表上的每个“元素”都长下图这个样子:</p><p><img src="https://cdn.xyxsw.site/boxcncRc5OKZROtxC9rpQYxrjvf.png" alt=""></p><p>数据域用来存储元素的值,指针域用来存放指针。数据结构中,通常将这样的整体称为结点。</p><p>也就是说,链表中实际存放的是一个一个的结点,数据元素存放在各个结点的数据域中。举个简单的例子,图 3 中 {1,2,3} 的存储状态用链表表示,如下图所示:</p><p><img src="https://cdn.xyxsw.site/boxcn0VMYQlez7tQTNkTPDkCsvg.png" alt=""></p><p>在 C 语言中,可以用结构体表示链表中的结点,例如:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">typedef</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> struct</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Node{</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> elem;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //代表数据域</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> struct</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Node </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> next;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //代表指针域,指向直接后继元素</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}Node;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">typedef</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> struct</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Node</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Link;</span></span></code></pre></div><h3 id="头结点、头指针和首元结点" tabindex="-1">头结点、头指针和首元结点 <a class="header-anchor" href="#头结点、头指针和首元结点" aria-label="Permalink to "头结点、头指针和首元结点""></a></h3><p>图 4 所示的链表并不完整,一个完整的链表应该由以下几部分构成:</p><p>头指针:是指向链表中一个结点所在存储位置的指针。如果链表中有头结点,则头指针指向头结点;若链表中没有头结点,则头指针指向链表中第一个数据结点(也叫首元结点)。</p><p>链表有头指针,当我们需要使用链表中的数据时,我们可以使用遍历查找等方法,从头指针指向的结点开始,依次搜索,直到找到需要的数据;反之,若没有头指针,则链表中的数据根本无法使用,也就失去了存储数据的意义。</p><p>结点:链表中的节点又细分为头结点、首元结点和其它结点:</p><p>头结点:位于链表的表头,即链表中第一个结点,其一般不存储任何数据,特殊情况可存储表示链表信息(表的长度等)的数据。</p><p>头结点的存在,其本身没有任何作用,就是一个空结点,但是在对链表的某些操作中,链表有无头结点,可以直接影响编程实现的难易程度。</p><p>例如,若链表无头结点,则对于在链表中第一个数据结点之前插入一个新结点,或者对链表中第一个数据结点做删除操作,都必须要当做特殊情况,进行特殊考虑;而若链表中设有头结点,以上两种特殊情况都可被视为普通情况,不需要特殊考虑,降低了问题实现的难度。</p><p><strong>链表有头结点,也不一定都是有利的。例如解决约瑟夫环问题,若链表有头结点,在一定程度上会阻碍算法的实现。</strong></p><p><strong>所以,对于一个链表来说,设置头指针是必要且必须的,但有没有头结点,则需要根据实际问题特殊分析。</strong></p><p>首元结点:指的是链表开头第一个存有数据的结点。</p><p>其他节点:链表中其他的节点。</p><p>也就是说,一个完整的链表是由头指针和诸多个结点构成的。每个链表都必须有头指针,但头结点不是必须的。</p><p>例如,创建一个包含头结点的链表存储 {1,2,3},如下图所示:</p><p><img src="https://cdn.xyxsw.site/boxcnjAoO54txAhnu7Ry8ExjGvc.png" alt=""></p><h2 id="链表的创建" tabindex="-1">链表的创建 <a class="header-anchor" href="#链表的创建" aria-label="Permalink to "链表的创建""></a></h2><p>创建一个链表,实现步骤如下:</p><ol><li>定义一个头指针;</li><li>创建一个头结点或者首元结点,让头指针指向它;</li><li>每创建一个结点,都令其直接前驱结点的指针指向它(尾插法/头插法)。</li></ol><h3 id="创建头指针和头结点-首元结点" tabindex="-1">创建头指针和头结点(首元结点) <a class="header-anchor" href="#创建头指针和头结点-首元结点" aria-label="Permalink to "创建头指针和头结点(首元结点)""></a></h3><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">typedef</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> struct</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Node{</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> elem;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //代表数据域</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> struct</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Node </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> next;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //代表指针域,指向直接后继元素</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}Node;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">typedef</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> struct</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Node</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Link;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-----------------------------------------------------------------------</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">Link</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> head </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (Link</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">malloc</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">sizeof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(Link));</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //创建头指针</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">head </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (Link)</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">malloc</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">sizeof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(Node));</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">//创建头结点(首元结点)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">head)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">elem </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> element;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">//头结点可以不存储数据或存储特殊数据</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">head)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">next </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> NULL</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">//初始头结点/首元结点的后继元素为空</span></span></code></pre></div><h3 id="创建结点——头插法" tabindex="-1">创建结点——头插法 <a class="header-anchor" href="#创建结点——头插法" aria-label="Permalink to "创建结点——头插法""></a></h3><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">Link p; </span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">while</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (Judgement)</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //for 同理</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (Link)</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">malloc</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">sizeof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(Node));</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p->elem </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> element;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p->next </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">head)->next;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">head)->next </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p><img src="https://cdn.xyxsw.site/boxcn8ZxT5oMkScArZjZhgM6TYb.png" alt=""></p><h3 id="创建结点——尾插法" tabindex="-1">创建结点——尾插法 <a class="header-anchor" href="#创建结点——尾插法" aria-label="Permalink to "创建结点——尾插法""></a></h3><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">Link p;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">Link r </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">head);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //临时中间结构指针,在尾插法中始终指向最后一个结点</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">while</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (Judgement)</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //for 同理</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (Link)</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">malloc</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">sizeof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(Node));</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p->elem </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> element;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p->next </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> NULL</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r->next </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p><img src="https://cdn.xyxsw.site/boxcnnMjc9pwgZgk1GBmBRlBS6d.png" alt=""></p><h2 id="链表的基本操作" tabindex="-1">链表的基本操作 <a class="header-anchor" href="#链表的基本操作" aria-label="Permalink to "链表的基本操作""></a></h2><p>学会创建链表之后,本节继续讲解链表的一些基本操作,包括向链表中添加数据、删除链表中的数据、读取、查找和更改链表中的数据。</p><h3 id="链表读取元素" tabindex="-1">链表读取元素 <a class="header-anchor" href="#链表读取元素" aria-label="Permalink to "链表读取元素""></a></h3><p>获得链表第 i 个数据的算法思路:</p><ol><li>声明一个结点 p 指向链表的第一个结点,初始化 j 从 1 开始;</li><li>当 j<i 时,就遍历链表,让 p 的指针向后移动,不断指向下一个结点,j 累加 1;</li><li>若到链表末尾 p 为空,则说明第 i 个元素不存在;</li><li>否则读取成功,返回结点 p 的数据</li></ol><p>实现代码如下:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> error</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> ok</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span></span>
|
||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">/*用 e 返回 L 中第 i 个数据元素的值*/</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> GetElem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(Link </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">L</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i; </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">e</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Link p; </span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">L)->next;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //p 指向第一个结点</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> j </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> while</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (p </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&&</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> j </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"><</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i)</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //p 不为空或者计数器 j 还没有等于 i 时,循环继续</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p->next;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //p 指向下一个结点</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> j</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">++</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">p)</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //第 i 个元素不存在</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> error;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">e </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p->elem;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //取第 i 个元素的数据</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ok;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>了解了链表如何读取元素,同理我们可以实现更新和查找链表元素。</p><h3 id="链表插入元素" tabindex="-1">链表插入元素 <a class="header-anchor" href="#链表插入元素" aria-label="Permalink to "链表插入元素""></a></h3><p>向链表中增添元素,根据添加位置不同,可分为以下 3 种情况:</p><ul><li>插入到链表的头部,作为首元节点;</li><li>插入到链表中间的某个位置;</li><li>插入到链表的最末端,作为链表中最后一个结点;</li></ul><p>对于有头结点的链表,3 种插入元素的实现思想是相同的,具体步骤是:</p><ol><li>将新结点的 next 指针指向插入位置后的结点;</li><li>将插入位置前结点的 next 指针指向插入结点;</li></ol><p>例如,在链表 <code>{1,2,3,4}</code> 的基础上分别实现在头部、中间、尾部插入新元素 5,其实现过程如图所示:</p><p><img src="https://cdn.xyxsw.site/boxcnxjex5Q3Lt9AAx6roN3ClUg.png" alt=""></p><p>从图中可以看出,虽然新元素的插入位置不同,但实现插入操作的方法是一致的,都是先执行步骤 1,再执行步骤 2。实现代码如下:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">/*在 L 中第 i 个位置(注意链表中的位置不一定为结点的个数)之前插入新的数据元素 e,</span></span>
|
||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">L 的长度加一(可以用头结点存储链表长度)*/</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> ListInsert</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(Link </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">L</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> i</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> e</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Link p, r;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //r 为临时中间结构指针,用于实现插入</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">L;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //p 指向头结点</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> j </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> while</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (p </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&&</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> j </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"><</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i)</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //寻找第 i 个结点,</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p->next;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> j</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">++</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">p)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> error;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (Link)</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">malloc</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">sizeof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(Node));</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r->elem </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> e;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r->next </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p->next;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p->next </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ok;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>注意:链表插入元素的操作必须是先步骤 1,再步骤 2;反之,若先执行步骤 2,除非再添加一个指针,作为插入位置后续链表的头指针,否则会导致插入位置后的这部分链表丢失,无法再实现步骤 1。</p><p>对于没有头结点的链表,在头部插入结点比较特殊,需要单独实现。</p><p><img src="https://cdn.xyxsw.site/boxcn1hlL1Fk4kDK4CPT2hJxwnV.png" alt=""></p><p>和 2)、3) 种情况相比,由于链表没有头结点,在头部插入新结点,此结点之前没有任何结点,实现的步骤如下:</p><ol><li>将新结点的指针指向首元结点;</li><li>将头指针指向新结点。</li></ol><p>实现代码如下:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">/*在 L 中第 i 个位置(注意链表中的位置不一定为结点的个数)之前插入新的数据元素 e,</span></span>
|
||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">L 的长度加一(可以用头结点存储链表长度)*/</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> ListInsert</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(Link </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">L</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> i</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> e</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (i </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">==</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Link r </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (Link)</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">malloc</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">sizeof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(Node));</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r->elem </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> e;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r->next </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">L)->next;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">L </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> else</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //......</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h3 id="链表删除元素" tabindex="-1">链表删除元素 <a class="header-anchor" href="#链表删除元素" aria-label="Permalink to "链表删除元素""></a></h3><p>从链表中删除指定数据元素时,实则就是将存有该数据元素的节点从链表中摘除。</p><p>对于有头结点的链表来说,无论删除头部(首元结点)、中部、尾部的结点,实现方式都一样,执行以下三步操作:</p><ol><li>找到目标元素所在结点的直接前驱结点;</li><li>将目标结点从链表中摘下来;</li><li>手动释放结点占用的内存空间;</li></ol><p>从链表上摘除目标节点,只需找到该节点的直接前驱节点 temp,执行如下操作:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">next</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">temp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">next</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">next;</span></span></code></pre></div><p>例如,从存有 <code>{1,2,3,4}</code> 的链表中删除存储元素 3 的结点,则此代码的执行效果如图 3 所示:</p><p><img src="https://cdn.xyxsw.site/boxcnn3QHja0tzEwqJl9Mk4KnCg.png" alt=""></p><p>实现代码如下:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">/*删除 L 中的第 i 个数据元素,并用 e 返回其值,L 的长度减一</span></span>
|
||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">(可以用头结点存储链表长度)*/</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> ListDelete</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(Link </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">L</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> i</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int*</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> e</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Link p, r;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">L;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> j </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> while</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (p->next </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&&</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> j </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"><</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i)</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //寻找删除元素中的前驱元素</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p->next;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> j</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">++</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(p->next))</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> error;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //L 中不存在第 i 个元素</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p->next;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //标记要删除的结点</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> p->next </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r->next;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //移除结点</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">e </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r->elem;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //返回结点所存数据</span></span>
|
||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> free</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(r);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //释放结点</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ok;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>对于不带头结点的链表,需要单独考虑删除首元结点的情况,删除其它结点的方式和图 3 完全相同,如下图所示:</p><p><img src="https://cdn.xyxsw.site/boxcnXjwE0yDFvpQxLaPw7FifxV.png" alt=""></p><p>实现代码如下:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">/*删除 L 中的第 i 个数据元素,并用 e 返回其值,L 的长度减一</span></span>
|
||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">(可以用头结点存储链表长度)*/</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> ListDelete</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(Link </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">L</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> i</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">int*</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> e</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (i </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">==</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Link r </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">L;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">L</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r->next;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">e </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> r->elem;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> free</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(r);</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> else</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //......</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h3 id="链表查找元素" tabindex="-1">链表查找元素 <a class="header-anchor" href="#链表查找元素" aria-label="Permalink to "链表查找元素""></a></h3><p>在链表中查找指定数据元素,最常用的方法是:从首元结点开始依次遍历所有节点,直至找到存储目标元素的结点。如果遍历至最后一个结点仍未找到,表明链表中没有存储该元素。</p><h3 id="链表更新元素" tabindex="-1">链表更新元素 <a class="header-anchor" href="#链表更新元素" aria-label="Permalink to "链表更新元素""></a></h3><p>更新链表中的元素,只需通过遍历找到存储此元素的节点,对节点中的数据域做更改操作即可。</p><h2 id="约瑟夫环" tabindex="-1">约瑟夫环 <a class="header-anchor" href="#约瑟夫环" aria-label="Permalink to "约瑟夫环""></a></h2><p>约瑟夫环问题,是一个经典的循环链表问题,题意是:已知 n 个人(分别用编号 1,2,3,…,n 表示)围坐在一张圆桌周围,从编号为 k 的人开始顺时针报数,数到 m 的那个人出列;他的下一个人又从 1 开始,还是顺时针开始报数,数到 m 的那个人又出列;依次重复下去,直到圆桌上剩余一个人。</p><p>如图所示,假设此时圆周周围有 5 个人,要求从编号为 3 的人开始顺时针数数,数到 2 的那个人出列:</p><p><img src="https://cdn.xyxsw.site/boxcngx7ZPA7pONbJo82LbNCO1g.png" alt=""></p><p>出列顺序依次为:</p><ul><li>编号为 3 的人开始数 1,然后 4 数 2,所以 4 先出列;</li><li>4 出列后,从 5 开始数 1,1 数 2,所以 1 出列;</li><li>1 出列后,从 2 开始数 1,3 数 2,所以 3 出列;</li><li>3 出列后,从 5 开始数 1,2 数 2,所以 2 出列;</li><li>最后只剩下 5 自己,所以 5 胜出。</li></ul><p>那么,究竟要如何用链表实现约瑟夫环呢?如何让一个含 5 个元素的约瑟夫环,能从第 5 个元素出发,访问到第 2 个元素呢?上面所讲的链表操作显然是难以做到的,解决这个问题就需要用到<strong>循环链表</strong>。</p><h2 id="循环链表" tabindex="-1">循环链表 <a class="header-anchor" href="#循环链表" aria-label="Permalink to "循环链表""></a></h2><p>将单链表中终端结点的指针端由空指针改为指向头结点,使得整个单链表形成一个环,这种头尾相接的单链表成为单循环链表,简称循环链表。</p><p>循环链表解决了一个很麻烦的问题。如何从当中一个结点出发,访问到链表的全部结点。</p><p>为了使空链表和非空链表处理一致,我们通常设一个头结点,当然,并不是说,循环链表一定要头结点,这需要注意。循环链表带有头结点的空链表如图所示:</p><p><img src="https://cdn.xyxsw.site/boxcn3l30usevMTgv1ZbZ0mfJdh.png" alt=""></p><p>对于非空的循环链表如图所示:</p><p><img src="https://cdn.xyxsw.site/boxcngoLTiM9wto9uCGzH7nkjkW.png" alt=""></p><p>循环链表和单链表的主要差异就在于循环的判断条件上,原来是判断 p->next 是否为空,现在则是 p->next 不等于头结点,则循环未结束。</p>`,100),l=[p];function k(t,e,E,r,d,g){return a(),i("div",null,l)}const o=s(h,[["render",k]]);export{c as __pageData,o as default};
|
||||
Reference in New Issue
Block a user