chore: 尝试切换到 ali oss

This commit is contained in:
camera-2018
2023-04-21 01:59:02 +08:00
parent 9a5d376115
commit 3cf4715781
81 changed files with 416 additions and 416 deletions

View File

@@ -6,13 +6,13 @@
使用链表存储数据,不强制要求数据在内存中集中存储,各个元素可以分散存储在内存中。例如,使用链表存储 {1,2,3},各个元素在内存中的存储状态可能是:
![](static/boxcnuwZzqX4dF8xKTYajwrDSxf.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcnuwZzqX4dF8xKTYajwrDSxf.png)
可以看到,数据不仅没有集中存放,在内存中的存储次序也是混乱的。那么,链表是如何存储数据间逻辑关系的呢?
链表存储数据间逻辑关系的实现方案是:为每一个元素配置一个指针,每个元素的指针都指向自己的直接后继元素,如下图所示:
![](static/boxcnAnkVAJmMT0NSNvo6crXYAd.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcnAnkVAJmMT0NSNvo6crXYAd.png)
显然,我们只需要记住元素 1 的存储位置,通过它的指针就可以找到元素 2通过元素 2 的指针就可以找到元素 3以此类推各个元素的先后次序一目了然。像图 2 这样,数据元素随机存储在内存中,通过指针维系数据之间“一对一”的逻辑关系,这样的存储结构就是链表。
@@ -20,13 +20,13 @@
在链表中,每个数据元素都配有一个指针,这意味着,链表上的每个“元素”都长下图这个样子:
![](static/boxcncRc5OKZROtxC9rpQYxrjvf.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcncRc5OKZROtxC9rpQYxrjvf.png)
数据域用来存储元素的值,指针域用来存放指针。数据结构中,通常将这样的整体称为结点。
也就是说,链表中实际存放的是一个一个的结点,数据元素存放在各个结点的数据域中。举个简单的例子,图 3 中 {1,2,3} 的存储状态用链表表示,如下图所示:
![](static/boxcn0VMYQlez7tQTNkTPDkCsvg.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcn0VMYQlez7tQTNkTPDkCsvg.png)
在 C 语言中,可以用结构体表示链表中的结点,例如:
@@ -66,7 +66,7 @@ typedef struct Node* Link;
例如,创建一个包含头结点的链表存储 {1,2,3},如下图所示:
![](static/boxcnjAoO54txAhnu7Ry8ExjGvc.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcnjAoO54txAhnu7Ry8ExjGvc.png)
## 链表的创建
@@ -104,7 +104,7 @@ while (Judgement)
}
```
![](static/boxcn8ZxT5oMkScArZjZhgM6TYb.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcn8ZxT5oMkScArZjZhgM6TYb.png)
### 创建结点——尾插法
@@ -121,7 +121,7 @@ while (Judgement) //for同理
}
```
![](static/boxcnnMjc9pwgZgk1GBmBRlBS6d.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcnnMjc9pwgZgk1GBmBRlBS6d.png)
## 链表的基本操作
@@ -176,7 +176,7 @@ int GetElem(Link *L, int i; int *e)
例如,在链表 `{1,2,3,4}` 的基础上分别实现在头部、中间、尾部插入新元素 5其实现过程如图所示
![](static/boxcnxjex5Q3Lt9AAx6roN3ClUg.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcnxjex5Q3Lt9AAx6roN3ClUg.png)
从图中可以看出,虽然新元素的插入位置不同,但实现插入操作的方法是一致的,都是先执行步骤 1 ,再执行步骤 2。实现代码如下
@@ -207,7 +207,7 @@ int ListInsert(Link *L, int i, int e)
对于没有头结点的链表,在头部插入结点比较特殊,需要单独实现。
![](static/boxcn1hlL1Fk4kDK4CPT2hJxwnV.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcn1hlL1Fk4kDK4CPT2hJxwnV.png)
和 2)、3) 种情况相比,由于链表没有头结点,在头部插入新结点,此结点之前没有任何结点,实现的步骤如下:
@@ -253,7 +253,7 @@ temp->next=temp->next->next;
例如,从存有 `{1,2,3,4}` 的链表中删除存储元素 3 的结点,则此代码的执行效果如图 3 所示:
![](static/boxcnn3QHja0tzEwqJl9Mk4KnCg.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcnn3QHja0tzEwqJl9Mk4KnCg.png)
实现代码如下:
@@ -282,7 +282,7 @@ int ListDelete(Link *L, int i, int* e)
对于不带头结点的链表,需要单独考虑删除首元结点的情况,删除其它结点的方式和图 3 完全相同,如下图所示:
![](static/boxcnXjwE0yDFvpQxLaPw7FifxV.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcnXjwE0yDFvpQxLaPw7FifxV.png)
实现代码如下:
@@ -319,7 +319,7 @@ int ListDelete(Link *L, int i, int* e)
如图所示,假设此时圆周周围有 5 个人,要求从编号为 3 的人开始顺时针数数,数到 2 的那个人出列:
![](static/boxcngx7ZPA7pONbJo82LbNCO1g.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcngx7ZPA7pONbJo82LbNCO1g.png)
出列顺序依次为:
@@ -339,10 +339,10 @@ int ListDelete(Link *L, int i, int* e)
为了使空链表和非空链表处理一致,我们通常设一个头结点,当然,并不是说,循环链表一定要头结点,这需要注意。循环链表带有头结点的空链表如图所示:
![](static/boxcn3l30usevMTgv1ZbZ0mfJdh.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcn3l30usevMTgv1ZbZ0mfJdh.png)
对于非空的循环链表如图所示:
![](static/boxcngoLTiM9wto9uCGzH7nkjkW.png)
![](https://hdu-cs-wiki.oss-cn-hangzhou.aliyuncs.com/boxcngoLTiM9wto9uCGzH7nkjkW.png)
循环链表和单链表的主要差异就在于循环的判断条件上,原来是判断 p->next 是否为空,现在则是 p->next 不等于头结点,则循环未结束。