带你理解单链表(如果对你有帮助的话请点赞呗)


🧨前言

本人目前是西安邮电大学计算机科学与技术专业一位普通的大学生,Q:1243032591
🧧我的码云主页点击这里🧧

这篇文章是我关于单链表写的文章,如果大家对于单链表的概念还不是很熟的话请点击这里
👉个人对于单链表的简单理解
按照我之前写代码的惯例,这次依旧分为三个文件 Sqlist.c Sqlist.h test.c
在这里插入图片描述


🚂Sqlist.h(函数声明,并且引用头文件和创建结构体)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include<stdio.h>
#include<stdlib.h>

typedef int datatype;
struct SqlistNode
{
datatype data;
struct SqlistNode* next;
};
typedef struct SqlistNode Sqt;

void SqlistPrint(Sqt* cur);
void SqlistPushback(Sqt** pphead, datatype x);
void SqlistPushFront(Sqt** pphead, datatype x);
void SqlistPopFront(Sqt** pphead);
void SqlistPopBack(Sqt** pphead);
Sqt* SqlistFind(Sqt*phead, datatype x);
void SqtlistInsert(Sqt** pphead,Sqt* pos, datatype x);
void SqtlistErase(Sqt** pphead, Sqt* pos);


⏩Sqlist.c(实现函数功能,用的时候记得包含Sqlist.h)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#define _CRT_SECURE_NO_WARNINGS 1
#include"Sqlist.h"
Sqt* BuyNode(datatype x)
{
Sqt* NewNode = (Sqt*)malloc(sizeof(Sqt));
if (NewNode != NULL)
{
NewNode->data = x;
NewNode->next = NULL;
}
return NewNode;
}
void SqlistPushback(Sqt** pphead,datatype x)
{
Sqt* NewNode = BuyNode(x);
Sqt* tail = NULL;
if (*pphead == NULL)
{
*pphead = NewNode;
}
else
{
tail = *pphead;
while (tail->next!=NULL)
{
tail = tail->next;
}
tail->next = NewNode;
}
}
void SqlistPushFront(Sqt** pphead, datatype x)
{
Sqt* NewNode = BuyNode(x);
NewNode->next = *pphead;
*pphead = NewNode;
}
void SqlistPrint(Sqt* cur)
{
while (cur!=NULL)
{
printf("%d -> ", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
void SqlistPopFront(Sqt** pphead)
{
Sqt* Next = (*pphead)->next;
free(*pphead);
*pphead = Next;
}
void SqlistPopBack(Sqt** pphead)
{
if (*pphead == NULL)
{
return;
}
else if((*pphead)->next==NULL)
{
free(*pphead);
*pphead = NULL;
}
else
{
Sqt* pre = NULL;
Sqt* tail = *pphead;
while (tail->next!=NULL)
{
pre = tail;
tail = tail->next;
}
free(tail);
pre->next = NULL;
}
}
Sqt* SqlistFind(Sqt* phead, datatype x)
{
Sqt* cur = phead;
while (cur)
{
if (cur->data == x)
return cur;
cur = cur->next;
}
return NULL;
}
void SqtlistInsert(Sqt** pphead, Sqt* pos, datatype x)
{
if (pos == *pphead)
{
SqlistPushFront(pphead,x);
}
else
{
Sqt* NewNode = BuyNode(x);
Sqt* pre = *pphead;
while (pre->next != pos)
{
pre = pre->next;
}
pre->next = NewNode;
NewNode->next = pos;
}

}
void SqtlistErase(Sqt** pphead, Sqt* pos)
{
if(*pphead==pos)
SqlistPopFront(pphead);
else
{
Sqt* pre = *pphead;
while (pre->next != pos)
{
pre = pre->next;
}
pre->next = pos->next;
free(pos);
}

}


🌹 test.c(输入数据并且测试,用的时候记得包含Sqlist.h)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#define _CRT_SECURE_NO_WARNINGS 1
#include"Sqlist.h"
void SqlistTest( )
{
Sqt* plist = NULL;
SqlistPushback(&plist,1);
SqlistPushback(&plist,2);
SqlistPushback(&plist,3);
SqlistPushFront(&plist, 0);
SqlistPrint(plist);
Sqt* pos = NULL;
/*if (pos)
{
SqtlistErase(&plist, pos);
}
SqlistPrint(plist);*/
pos = SqlistFind(plist, 0);
if (pos)
{
SqtlistInsert(&plist, pos, 5);
}
SqlistPrint(plist);
/*SqlistPopFront(&plist);
SqlistPrint(plist);
SqlistPopFront(&plist);
SqlistPrint(plist);
SqlistPopBack(&plist);
SqlistPrint(plist);
SqlistPopBack(&plist);
SqlistPrint(plist);
SqlistPopBack(&plist);
SqlistPrint(plist);*/
}

int main(void)
{
SqlistTest();
return 0;
}


🍕接下来是单链表中的函数具体实现

🦺插入数据

🚂申请空间 BuyNode

单链表每次插入数据都要申请一块空间,可以理解为火车要装货物得用车厢装货物然后将单节车厢连接到火车后面

1
2
3
4
5
6
7
8
9
10
11
Sqt* BuyNode(datatype x)
{
Sqt* NewNode = (Sqt*)malloc(sizeof(Sqt));
if (NewNode != NULL)
{
NewNode->data = x;
NewNode->next = NULL;
}
return NewNode;
}


🚂头插 SqlistPushFront

1
2
3
4
5
6
7
void  SqlistPushFront(Sqt** pphead, datatype x)
{
Sqt* NewNode = BuyNode(x);
NewNode->next = *pphead;
*pphead = NewNode;
}


🚂尾插 SqlistPushback

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void SqlistPushback(Sqt** pphead,datatype x)
{
Sqt* NewNode = BuyNode(x);
Sqt* tail = NULL;
if (*pphead == NULL)
{
*pphead = NewNode;
}
else
{
tail = *pphead;
while (tail->next!=NULL)
{
tail = tail->next;
}
tail->next = NewNode;
}
}


🚂在指定数据之前插入数据 SqtlistInsert

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void SqtlistInsert(Sqt** pphead, Sqt* pos, datatype x)
{
if (pos == *pphead)
{
SqlistPushFront(pphead,x);
}
else
{
Sqt* NewNode = BuyNode(x);
Sqt* pre = *pphead;
while (pre->next != pos)
{
pre = pre->next;
}
pre->next = NewNode;
NewNode->next = pos;
}

}


🚂删除数据

🚂头删 SqlistPopFront

1
2
3
4
5
6
7
8
9
10
11
void SqlistPopFront(Sqt** pphead)
{
if (*pphead == NULL)
{
return;
}
Sqt* Next = (*pphead)->next;
free(*pphead);
*pphead = Next;
}


🚂尾删 SqlistPopBack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void SqlistPopBack(Sqt** pphead)
{
if (*pphead == NULL)
{
return;
}
else if((*pphead)->next==NULL)
{
free(*pphead);
*pphead = NULL;
}
else
{
Sqt* pre = NULL;
Sqt* tail = *pphead;
while (tail->next!=NULL)
{
pre = tail;
tail = tail->next;
}
free(tail);
pre->next = NULL;
}
}


🚂删除指定数据 SqtlistErase

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void SqtlistErase(Sqt** pphead, Sqt* pos)
{
if(*pphead==pos)
SqlistPopFront(pphead);
else
{
Sqt* pre = *pphead;
while (pre->next != pos)
{
pre = pre->next;
}
pre->next = pos->next;
free(pos);
}



🚂查找数据 SqlistFind

如果找到了的话返回该节点的指针(地址),如果找不到就返回NULL

1
2
3
4
5
6
7
8
9
10
11
12
Sqt* SqlistFind(Sqt* phead, datatype x)
{
Sqt* cur = phead;
while (cur)
{
if (cur->data == x)
return cur;
cur = cur->next;
}
return NULL;
}


🚂打印数据 SqlistPrint

1
2
3
4
5
6
7
8
9
10
void SqlistPrint(Sqt* cur)
{
while (cur!=NULL)
{
printf("%d -> ", cur->data);
cur = cur->next;
}
printf("NULL\n");
}


🎉结语

单链表这一期就完结撒花啦🍻,很感谢大家能看到这里,希望这篇文章对大家有帮助,如果大家有什么好的见解或者有什么疑问的话欢迎大家评论或者联系我。


带你理解单链表(如果对你有帮助的话请点赞呗)
https://6jackjiang.github.io/2022/03/13/categories/C语言/带你理解单链表(如果对你有帮助的话请点赞呗)/
作者
米兰的小铁匠
发布于
2022年3月13日
许可协议