chore: add 3.4.3
chore: add 3.4.4 chore: add 3.4.5 chore: add 3.4.5.1 chore: add 3.4.6.1 chore: add 3.4.6.2 chore: add 3.4.6.3 chore: add 3.4.6.4 chore: add 3.4.6.5
This commit is contained in:
@@ -42,13 +42,13 @@ typedef struct Node* Link;
|
||||
|
||||
图 4 所示的链表并不完整,一个完整的链表应该由以下几部分构成:
|
||||
|
||||
头指针:是指向链表中一个结点所在存储位置的指针。如果链表中有头结点,则头指针指向头结点;若链表中没有头结点,则头指针指向链表中第一个数据结点(也叫首元结点)。
|
||||
头指针:是指向链表中一个结点所在存储位置的指针。如果链表中有头结点,则头指针指向头结点;若链表中没有头结点,则头指针指向链表中第一个数据结点(也叫首元结点)。
|
||||
|
||||
链表有头指针,当我们需要使用链表中的数据时,我们可以使用遍历查找等方法,从头指针指向的结点开始,依次搜索,直到找到需要的数据;反之,若没有头指针,则链表中的数据根本无法使用,也就失去了存储数据的意义。
|
||||
|
||||
结点:链表中的节点又细分为头结点、首元结点和其它结点:
|
||||
|
||||
头结点:位于链表的表头,即链表中第一个结点,其一般不存储任何数据,特殊情况可存储表示链表信息(表的长度等)的数据。
|
||||
头结点:位于链表的表头,即链表中第一个结点,其一般不存储任何数据,特殊情况可存储表示链表信息(表的长度等)的数据。
|
||||
|
||||
头结点的存在,其本身没有任何作用,就是一个空结点,但是在对链表的某些操作中,链表有无头结点,可以直接影响编程实现的难易程度。
|
||||
|
||||
@@ -95,7 +95,7 @@ Link* head = (Link*)malloc(sizeof(Link)); //创建头指针
|
||||
|
||||
```c
|
||||
Link p;
|
||||
while (Judgement) //for同理
|
||||
while (Judgement) //for 同理
|
||||
{
|
||||
p = (Link)malloc(sizeof(Node));
|
||||
p->elem = element;
|
||||
@@ -111,7 +111,7 @@ while (Judgement)
|
||||
```c
|
||||
Link p;
|
||||
Link r = (*head); //临时中间结构指针,在尾插法中始终指向最后一个结点
|
||||
while (Judgement) //for同理
|
||||
while (Judgement) //for 同理
|
||||
{
|
||||
p = (Link)malloc(sizeof(Node));
|
||||
p->elem = element;
|
||||
@@ -141,20 +141,20 @@ while (Judgement) //for同理
|
||||
```c
|
||||
#define error 0
|
||||
#define ok 1
|
||||
/*用e返回L中第i个数据元素的值*/
|
||||
/*用 e 返回 L 中第 i 个数据元素的值*/
|
||||
int GetElem(Link *L, int i; int *e)
|
||||
{
|
||||
Link p;
|
||||
p = (*L)->next; //p指向第一个结点
|
||||
p = (*L)->next; //p 指向第一个结点
|
||||
int j = 1;
|
||||
while (p && j < i) //p不为空或者计数器j还没有等于i时,循环继续
|
||||
while (p && j < i) //p 不为空或者计数器 j 还没有等于 i 时,循环继续
|
||||
{
|
||||
p = p->next; //p指向下一个结点
|
||||
p = p->next; //p 指向下一个结点
|
||||
j++;
|
||||
}
|
||||
if (!p) //第i个元素不存在
|
||||
if (!p) //第 i 个元素不存在
|
||||
return error;
|
||||
*e = p->elem; //取第i个元素的数据
|
||||
*e = p->elem; //取第 i 个元素的数据
|
||||
return ok;
|
||||
}
|
||||
```
|
||||
@@ -178,17 +178,17 @@ int GetElem(Link *L, int i; int *e)
|
||||
|
||||

|
||||
|
||||
从图中可以看出,虽然新元素的插入位置不同,但实现插入操作的方法是一致的,都是先执行步骤 1 ,再执行步骤 2。实现代码如下:
|
||||
从图中可以看出,虽然新元素的插入位置不同,但实现插入操作的方法是一致的,都是先执行步骤 1,再执行步骤 2。实现代码如下:
|
||||
|
||||
```c
|
||||
/*在L中第i个位置(注意链表中的位置不一定为结点的个数)之前插入新的数据元素e,
|
||||
L的长度加一(可以用头结点存储链表长度)*/
|
||||
/*在 L 中第 i 个位置(注意链表中的位置不一定为结点的个数)之前插入新的数据元素 e,
|
||||
L 的长度加一(可以用头结点存储链表长度)*/
|
||||
int ListInsert(Link *L, int i, int e)
|
||||
{
|
||||
Link p, r; //r为临时中间结构指针,用于实现插入
|
||||
p = *L; //p指向头结点
|
||||
Link p, r; //r 为临时中间结构指针,用于实现插入
|
||||
p = *L; //p 指向头结点
|
||||
int j = 1;
|
||||
while (p && j < i) //寻找第i个结点,
|
||||
while (p && j < i) //寻找第 i 个结点,
|
||||
{
|
||||
p = p->next;
|
||||
j++;
|
||||
@@ -217,8 +217,8 @@ int ListInsert(Link *L, int i, int e)
|
||||
实现代码如下:
|
||||
|
||||
```c
|
||||
/*在L中第i个位置(注意链表中的位置不一定为结点的个数)之前插入新的数据元素e,
|
||||
L的长度加一(可以用头结点存储链表长度)*/
|
||||
/*在 L 中第 i 个位置(注意链表中的位置不一定为结点的个数)之前插入新的数据元素 e,
|
||||
L 的长度加一(可以用头结点存储链表长度)*/
|
||||
int ListInsert(Link *L, int i, int e)
|
||||
{
|
||||
if (i == 1)
|
||||
@@ -258,7 +258,7 @@ temp->next=temp->next->next;
|
||||
实现代码如下:
|
||||
|
||||
```c
|
||||
/*删除L中的第i个数据元素,并用e返回其值,L的长度减一
|
||||
/*删除 L 中的第 i 个数据元素,并用 e 返回其值,L 的长度减一
|
||||
(可以用头结点存储链表长度)*/
|
||||
int ListDelete(Link *L, int i, int* e)
|
||||
{
|
||||
@@ -271,7 +271,7 @@ int ListDelete(Link *L, int i, int* e)
|
||||
j++;
|
||||
}
|
||||
if (!(p->next))
|
||||
return error; //L中不存在第i个元素
|
||||
return error; //L 中不存在第 i 个元素
|
||||
r = p->next; //标记要删除的结点
|
||||
p->next = r->next; //移除结点
|
||||
*e = r->elem; //返回结点所存数据
|
||||
@@ -287,7 +287,7 @@ int ListDelete(Link *L, int i, int* e)
|
||||
实现代码如下:
|
||||
|
||||
```c
|
||||
/*删除L中的第i个数据元素,并用e返回其值,L的长度减一
|
||||
/*删除 L 中的第 i 个数据元素,并用 e 返回其值,L 的长度减一
|
||||
(可以用头结点存储链表长度)*/
|
||||
int ListDelete(Link *L, int i, int* e)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user