
🎈主页传送门****:良木生香
🌟人为善,福随未至,祸已远行;人为恶,祸虽未至,福已远离
目录
**上期回顾:**在上一篇文章中(这是链接:【数据结构-初阶】详解线性表(1)---顺序表),我们学习了第一种数据结构---顺序表,这是一种逻辑上连续,物理上也连续的数据存储方式,文章中我们也提到,也有逻辑上连续,但物理上不连续的数据存储方式,那这就是我今天分享的内容了------单链表
前言:在开始之前,我想先与大家探讨探讨什么是链表.都说链表链表,那顾名思义就是像有链子一样把数据串起来的表格吧.那具体是啥呢?又有哪些分类与作用呢?接下来我们一一讲解
1、链表
1.1、什么是链表?
概念 :链表是一种物理存储结构上非连续、非顺序的存储结构,数据的元素逻辑顺序是通过链表中的指针次序实现的。
单单这样子讲大家可能会有些疑惑,链表到底是什么啊!!!不着急,我就拿火车来给大家举个例子吧。火车是有一节一节车厢的,每节车厢是由车厢之间的挂钩连接在一起的,那么链表的节点就相当于每节车厢,而每个节点里面所存放的指针就相当于车厢之间的挂钩:

**链表中的每个节点都存放着当前节点的数组data,我们将其称之为---****数据域,****以及下一个节点的指针,我们将其称之为---****指针域,**当我们在对链进行操作时,就可以通过当前链表所存放的指针来找到下一个链表节点.
1.2、链表的分类
在链表这个大家族中,有许多种类的链表,有我们今天要讲的单链表,也有后面会学到的双链表,有带头节点的,也有不带头节点的,有循环也有不循环的,下面一张图带你了解链表的分类:

这样的话,链表就被分成了八个类别,而我们今天要讲的就是,单项不带头结点不循环链表.
2、单链表的实现
讲完了链表的概念之后,下面我们就正式进入单链表的学习之中。
2.1、单链表的头文件
在实现链表之前,我们先将所需要的头文件写好:
cpp
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h> //基本函数的使用
#include<stdlib.h> //为了使用动态内存管理函数
#include<windows.h> //为了实现清屏的功能
#include<assert.h> //用于指针断言
//接下来的代码的是实现单向不带头节点不循环链表
//现在重命名变量
typedef int Elemtype;
实现单链表的功能.我们依旧可以通过增、删、查、改四个方向来操作
2.2、单链表的结构
单链表的操作是对每个车厢节点进行操作的,那现在我们来构建它的车厢节点的基本结构,主要有数据域 和指针域组成:
像现在来看看我们的结构体代码
cpp
typedef struct ListNode {
Elemtype data;
ListNode* next;
}ListNode;
这样子写家人们认为对吗?我让这个结构体指针next指向ListNode*类型的,这样写可以吗?
当然不行,为啥?因为C语言是向上编译的,也就是说,在编译的时候,程序会向上寻找ListNode类型的变量,但是它只能找到struct ListNode*,换句话说就是ListNode这个重命名的名字是在结构体生成之后才有的,而在结构体里面没有这个名字,所以不能用重命名的名字对结构体里面的变量命名,正确的代码如下:
cpp
typedef struct ListNode {
Elemtype data;
struct ListNode* next;
}ListNode;
next指针应该用struct ListNode 类型,经过最后的重命名为ListNode之后,后续再调用next就可以用ListNode* 类型了.
2.3、单链表节点的创建
我们现在已经知道了,链表是由一个一个节点连在一起的,那么我们对链表进行操作,实际上就是对链表的节点进行操作,这里少不了的就是创建,也就是向内存申请空间:
cpp
//现在是创建链表节点的函数
ListNode* Buy_Node(Elemtype data) {
//向内存申请空间
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
if (newNode == NULL) {
printf("申请空间失败\n");
return NULL;
}
newNode->data = data;
newNode->next = NULL;
return newNode;
}
在这个函数中,我们传入一个参数data,作为数据域的数据,然后向内存申请大小为ListNode的空间存放链表节点,将data赋值给节点中的data变量,并将要指向下一个节点的指针next置为NULL,因为现在只是创建节点,并不用指向某个节点.
2.4、单链表的初始化
对于单链表的初始化,这里就有讲究了。我们今天要实现的是不带头结点的单项不循环链表,那么就不会有头结点,也就是意味着,头结点(也叫做哨兵位)与链表的第一个节点是重合的,不明白什么意思的话就看看下面这张图:


对于这种没有头节点的,我们初始化的方法就不一样了,我们是对第一个节点的指针进行初始化(本质上是对指针内容进行修改),因为在最开始的时候还没有创建链表节点,所以我们要将指向第一个节点的指针置为NULL,这就算是初始化成功了
但是想要修改一个指针的内容,我们应该怎么呢?当然是闯入这个指针的地址,用二级指针接收,图示如下:

初始化的本质就是将头指针置为NULL!!!!!!
代码如下:
cpp
void Init_ListNode(ListNode** pphead) {
assert(pphead); //记得对传进来的指针进行断言
*pphead = NULL;
}
2.5、单链表的插入操作
插入操作与顺序表一样,同样分为头插,尾插 ,pos之前之后插入,下面就来一一实现:
2.5.1、单链表的头部插入
对于头部插入,实现的是使数据先进后出的功能,这会让头指针不断改变指向的节点,想要修改头指针指向的节点,我们就要用二级指针来接收头指针的地址,通过头指针的二级指针改头指针的指向节点:

我们要将头结点不断修改,保证他能一直指向新加入的节点.明白了插入的流程之后,那我们就上代码吧~~~~
cpp
void Push_Front(ListNode** pphead, Elemtype data) {
assert(pphead); //对指针进行断言
ListNode* newNode = Buy_Node(data); //创建新节点
if (newNode == NULL) {
printf("创建新节点失败...\n");
return;
}
//newnode *pphead
newNode->next = *pphead; //连接新新节点与头指针
*pphead = newNode; //将头指针指向新节点
}
小贴士:记得传入数据data~~~
2.5.2、单链表的尾部插入
尾部插入与头部插入大相庭径,只要找到最后一个节点,将新节点连接到最后一个节点即可.因为要找到尾结点,所以我们要传入头结点,定义一个遍历链表的节点来找到尾结点:

代码如下:
cpp
void Push_Back(ListNode** pphead, Elemtype data) {
assert(pphead);
ListNode* newNode = Buy_Node(data);
//判断是否为头节点
if (*pphead == NULL) {
*pphead = newNode;
return;
}
// *pphead *pphead->next newNode
// ptail
else {
ListNode* ptail = *pphead;
while (ptail->next != NULL) {
ptail = ptail->next;
}
ptail->next = newNode;
}
}
小贴士:再插入之前,我们要先判断是否存在头结点,如果不存在头结点,我们要将头指针指向该节点
2.5.3、单链表的pos位置插入
2.5.3.1、单链表的长度计算
我们先对链表长度进行计算,后面可能会用到,就算用不到,我们也可以多出一个求长度的功能.求长度的基本思路就是用一个遍历链表的指针,计算节点的指针,代码如下:
cpp
int Get_ListLength(ListNode** pphead) {
assert(pphead); //依旧记得断言指针
int len = 0;
ListNode* pcur = *pphead;
while (pcur != NULL) {
len++;
pcur = pcur->next;
}
return len;
}
小贴士:在while()循环条件中,不能写pcur->next!=NULL,因为这样会让指针最终指向的只是倒数第二个节点,不能完全计算链表的长度
2.5.3.2、查找pos位置上的元素
想要对pos位置前后进行操作,就要先判断pos这个位置是否存在元素,如果有就返回pos位置上节点的指针,以便于后续的操作:
cpp
ListNode* Search_pos_elem(ListNode** pphead, int pos) {
assert(pphead);
int len = Get_ListLength(pphead);
if (pos < 0||pos>len) {
printf("pos值不合法...\n");
return NULL;
}
ListNode* ppos = *pphead;
if(pos == 1){
return *pphead;
}
for (int i = 1; i < pos; i++) {
if (ppos == NULL) {
printf("pos位置没有元素...\n");
return NULL;
}
ppos = ppos->next;
}
return ppos;
}
小贴士:在查找pos位置上的元素时,要先判断pos值的合法性,在看看pos是不是==1,如果是就返回第一个节点,最后在进行遍历.
2.5.3.3、pos位置之前的插入
我们可以通过一下步骤进行操作:
1.判断pos值
2.if(pos==1),那就头插,else:找出pos位置节点,再找出pos的前一个节点prev_node
3.在prev_node与pos之间进行插入操作

代码如下:
cpp
void Push_pos_Front(ListNode** pphead, Elemtype data, int pos) {
assert(pphead);
//ListNode* PosNode = Search_elem_for_posFront(pphead, pos);
ListNode* newNode = Buy_Node(data);
int len = Get_ListLength(pphead);
if (pos<1 || pos>len) {
printf("pos值不合法,该位置无法插入...\n");
return;
}
if (pos == 1) {
//相当于头插
Push_Front(pphead, data);
return;
}
else {
ListNode* pos_node = Search_pos_elem(pphead, pos);
ListNode* prev = *pphead;
while (prev->next != pos_node) {
prev = prev->next;
}
//prev_node newNode pos
newNode->next = pos_node;
prev->next = newNode;
}
}
小贴士:该函数涉及多个函调用,在操作的时候要小心哦
2.5.3.4、pos位置之后的插入
这个操作会比上一个简单,只需要找到pos位置的节然后进行操作即可,步骤与前一个就少了找到prev_node节点而已,

直接上代码:
cpp
void Push_pos_Back(ListNode** pphead, Elemtype data, int pos) {
assert(pphead);
ListNode* newNode = Buy_Node(data);
ListNode* PosNode = Search_pos_elem(pphead, pos);
if (PosNode == NULL) {
return;
}
//PosNode newNode PosNode->next;
newNode->next = PosNode->next;
PosNode->next = newNode;
}
那么以上就是单链表插入操作的所有代码了,有不对的地方希望大佬们指出来~~~
2.6、单链表的删除操作
2.6.1、单链表的头部删除
单链表的头部删除依旧是涉及到头指针的指向问题,那么我们就要传入头指针的指针,操作相对简单,但是要注意的是,要先给头结点赋值上一个删除的指针变量,将现在头结点的指针指向下一个节点,在释放删除的指针变量

代码如下:
cpp
void Pop_Front(ListNode** pphead) {
assert(pphead);
//*pphead *pphead->next *pphead->next->next
//delet *pphead
if (*pphead == NULL) {
printf("链表为空,无法删除...\n");
return;
}
ListNode* delet = *pphead;
*pphead = delet->next;
free(delet);
delet = NULL;
}
小贴士:释放空间之后记得将delet指针置为空哦,不然会成为野指针的~~~~~
2.6.2、单链表的尾部删除
想要进行单链表的尾删,就少不了找出尾指针,肯定是需要遍历的,具体过程可以看下图,步骤与头删相类似:

小贴士:释放完空间之后记得将delet指针置为NULL~~~
2.6.3、单链表的pos位置删除
因为删除是对单个元素进行操作的,就不用分pos之前和pos之后了,直接删掉就行,要注意的是,删掉pos位置节点之后,要处理好pos前后节点的连接:

下面上代码:
cpp
//现在是实现pos位置的删除
void Pop_pos(ListNode** pphead, int pos) {
assert(pphead);
int len = Get_ListLength(pphead);
if (pos < 1||pos>len) {
printf("pos位置不合法...\n");
return;
}
if (*pphead == NULL) {
printf("链表为空,无法删除...\n");
return;
}
if (pos == 1) {
Pop_Front(pphead);
return;
}
//先查找pos位置的元素;
ListNode* PosNode = Search_pos_elem(pphead, pos);
if (PosNode == NULL) {
printf("该位置没有元素...\n");
return;
}
//ppos PosNode PosNode->next
//ppos delet
ListNode* ppos = *pphead;
while (ppos->next != PosNode) {
ppos = ppos->next;
}
ListNode* delet = PosNode;
ppos->next = delet->next;
free(delet);
delet = NULL;
PosNode = NULL;
}
小贴士:在删除的时候我们要判断好头结点与空链表,最后韩信带净化(还是那句话),记得将delet指针值为NULL
2.7、单链表的查找操作
这个查找的操作是用已知元素去检验目标元素是否存在,只需要遍历一次链表即可:
cpp
//现在是查找目标元素函数
void Search_elem(ListNode** pphead, Elemtype data) {
assert(pphead);
ListNode* pcur = *pphead;
int count = 0;
int flag = 0;
while (pcur != NULL) {
count++;
if (pcur->data == data) {
printf("找到了!在第%d个位置\n", count);
flag = 1;
break;
}
pcur = pcur->next;
}
if (flag == 0) {
printf("没找到你想要的元素...\n");
}
}
小贴士:我们要注意,有两种情况会退出循环:
1.找到元素了.退出循环;
2.遍历整个数组,都没有找到,退出循环.
我们自然要对于这两种情况进行区分
2.8、单链表的修改操作
这个操作是整个操作系列中最简单的了,只用找到pos位置元素,直接修改即可:
cpp
//现在实现修改功能
void Change_elem_pos(ListNode** pphead, int pos, Elemtype data) {
assert(pphead);
int len = Get_ListLength(pphead);
if (pos < 1 || pos>len) {
printf("pos值不合法...\n");
return;
}
//依旧先查找
ListNode* PosNode = Search_pos_elem(pphead, pos);
if (PosNode == NULL) {
printf("该位置没有元素,无法修改...\n");
return;
}
PosNode->data = data;
}
小贴士:要注意判断pos的值是否合法~~~
2.9单链表的打印
这个操作只用遍历,然后纯纯输出:
cpp
//现在是打印链表函数
void my_printf(ListNode* phead) {
//assert(phead);
if (phead == NULL)
{
printf("当前链表为空...\n");
return;
}
ListNode* pcur = phead;
while (pcur != NULL) {
printf("%d ", pcur->data);
pcur = pcur->next;
}
printf("\n");
}
小贴士:没有小贴士~~~
2.10、单链表的销毁
韩信带净化(还是那句话),遍历链表,逐个节点逐个节点地销毁
cpp
//现在是销毁链表函数
void Destory_ListNode(ListNode** pphead) {
assert(pphead);
ListNode* pcur = *pphead;
while (pcur != NULL) {
ListNode* delet = pcur;
pcur = pcur->next;
free(delet);
delet = NULL;
}
*pphead = NULL;
pcur = NULL;
}
小贴士:最后记得将头指针与delet、pcur置为空~~~~
3、总体实现:
既然上面讲了这么多,现在我们就来将代码们整合一下吧~~~有点长,嘻嘻
cpp
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<assert.h>
//接下来的代码的是实现单向不带头节点链表
//现在重命名变量
typedef int Elemtype;
//现在定义链表结构
typedef struct ListNode {
Elemtype data;
struct ListNode* next;
}ListNode;
//基本的函数声明
void Init_ListNode(ListNode** phead); //初始化
ListNode* Buy_Node(Elemtype data); //创建新节点
int Get_ListLength(ListNode** pphead); //计算链表长度
//插入
void Push_Front(ListNode** pphead, Elemtype data); //头插
void Push_Back(ListNode** pphead, Elemtype data); //尾插
//ListNode* Search_elem_for_posFront(ListNode** pphead, int pos); //查找pos位置的前一个元素
void Push_pos_Front(ListNode** pphead, Elemtype data, int pos); //pos位置之前插入
ListNode* Search_pos_elem(ListNode** pphead, int pos); //查找pos位置上的元素
void Push_pos_Back(ListNode** pphead, Elemtype data, int pos); //pos位置之后插入
//删除
void Pop_Front(ListNode** pphead); //头删
void Pop_Back(ListNode** pphead); //尾删
void Pop_pos(ListNode** pphead, int pos); //pos位置删除
//修改
void Change_elem_pos(ListNode** pphead, int pos, Elemtype data);
//查找
void Search_elem(ListNode** pphead, Elemtype data);
//其他
void my_printf(ListNode* phead); //打印链表
void Destory_ListNode(ListNode** pphead); //销毁链表
void printf_menu(); //打印菜单
//现在是初始化链表
void Init_ListNode(ListNode** pphead) {
assert(pphead);
*pphead = NULL;
}
//现在是创建链表节点的函数
ListNode* Buy_Node(Elemtype data) {
//向内存申请空间
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
if (newNode == NULL) {
printf("申请空间失败\n");
return NULL;
}
newNode->data = data;
newNode->next = NULL;
return newNode;
}
//计算链表长度
int Get_ListLength(ListNode** pphead) {
assert(pphead);
int len = 0;
ListNode* pcur = *pphead;
while (pcur != NULL) {
len++;
pcur = pcur->next;
}
return len;
}
//现在实现链表
//插入操作:头部插入:
void Push_Front(ListNode** pphead, Elemtype data) {
assert(pphead);
ListNode* newNode = Buy_Node(data);
if (newNode == NULL) {
printf("创建新节点失败...\n");
return;
}
//newnode *pphead
newNode->next = *pphead;
*pphead = newNode;
}
//现在是尾部插入
void Push_Back(ListNode** pphead, Elemtype data) {
assert(pphead);
ListNode* newNode = Buy_Node(data);
//判断是否为头节点
if (*pphead == NULL) {
*pphead = newNode;
return;
}
// *pphead *pphead->next newNode
// ptail
else {
ListNode* ptail = *pphead;
while (ptail->next != NULL) {
ptail = ptail->next;
}
ptail->next = newNode;
}
}
//现在是pos位置之前的插入
//现在这个函数是寻找pos位置的元素,看看pos位置之前的一个位置是否有元素
ListNode* Search_elem_for_posFront(ListNode** pphead, int pos) {
assert(pphead);
int len = Get_ListLength(pphead);
if (pos<1 || pos>len + 1) {
printf("pos值不合法,链表长度为:%d", len);
return NULL;
}
if (pos == 1) {
return NULL;
}
ListNode* ppos = *pphead;
for (int i = 1; i < pos - 1; i++) {
if (ppos == NULL) {
printf("pos位置没有元素...\n");
return NULL;
}
ppos = ppos->next;
}
if (ppos == NULL) {
printf("pos位置没有元素...\n");
return NULL;
}
return ppos;
}
//先在再来实现pos位置之前插入
void Push_pos_Front(ListNode** pphead, Elemtype data, int pos) {
assert(pphead);
//ListNode* PosNode = Search_elem_for_posFront(pphead, pos);
ListNode* newNode = Buy_Node(data);
int len = Get_ListLength(pphead);
if (pos<1 || pos>len) {
printf("pos值不合法,该位置无法插入...\n");
return;
}
if (pos == 1) {
//相当于头插
Push_Front(pphead, data);
return;
}
else {
ListNode* pos_node = Search_pos_elem(pphead, pos);
ListNode* prev = *pphead;
while (prev->next != pos_node) {
prev = prev->next;
}
//prev_node newNode pos
newNode->next = pos_node;
prev->next = newNode;
}
}
//现在实现查找pos位置元素的函数,本质上是为了给pos位置之后插入进行辅助,但是同时也实现了查找的功能
ListNode* Search_pos_elem(ListNode** pphead, int pos) {
assert(pphead);
int len = Get_ListLength(pphead);
if (pos < 0||pos>len) {
printf("pos值不合法...\n");
return NULL;
}
ListNode* ppos = *pphead;
if (pos == 1) {
return *pphead;
}
for (int i = 1; i < pos; i++) {
if (ppos == NULL) {
printf("pos位置没有元素...\n");
return NULL;
}
ppos = ppos->next;
}
return ppos;
}
//现在是实现pos位置之后来实现插入
void Push_pos_Back(ListNode** pphead, Elemtype data, int pos) {
assert(pphead);
ListNode* newNode = Buy_Node(data);
ListNode* PosNode = Search_pos_elem(pphead, pos);
if (PosNode == NULL) {
return;
}
//PosNode newNode PosNode->next;
newNode->next = PosNode->next;
PosNode->next = newNode;
}
//现在是实现删除元素
//头删
void Pop_Front(ListNode** pphead) {
assert(pphead);
//*pphead *pphead->next *pphead->next->next
//delet *pphead
if (*pphead == NULL) {
printf("链表为空,无法删除...\n");
return;
}
ListNode* delet = *pphead;
*pphead = delet->next;
free(delet);
delet = NULL;
}
//现在是实现尾部删除的操作;
void Pop_Back(ListNode** pphead) {
assert(pphead);
//定义尾指针
if (*pphead == NULL) {
printf("链表为空,无法删除...\n");
return;
}
if ((*pphead)->next == NULL) {
free(*pphead);
*pphead = NULL;
return;
}
ListNode* ptail = *pphead;
while (ptail->next->next != NULL) {
ptail = ptail->next;
}
//ptail ptail->next NULL
// ptail delet
ListNode* delet = ptail->next;
ptail->next = NULL;
free(delet);
delet = NULL;
}
//现在是实现pos位置的删除
void Pop_pos(ListNode** pphead, int pos) {
assert(pphead);
int len = Get_ListLength(pphead);
if (pos < 1||pos>len) {
printf("pos位置不合法...\n");
return;
}
if (*pphead == NULL) {
printf("链表为空,无法删除...\n");
return;
}
if (pos == 1) {
Pop_Front(pphead);
return;
}
//先查找pos位置的元素;
ListNode* PosNode = Search_pos_elem(pphead, pos);
if (PosNode == NULL) {
printf("该位置没有元素...\n");
return;
}
//ppos PosNode PosNode->next
//ppos delet
ListNode* ppos = *pphead;
while (ppos->next != PosNode) {
ppos = ppos->next;
}
ListNode* delet = PosNode;
ppos->next = delet->next;
free(delet);
delet = NULL;
PosNode = NULL;
}
//现在实现修改功能
void Change_elem_pos(ListNode** pphead, int pos, Elemtype data) {
assert(pphead);
int len = Get_ListLength(pphead);
if (pos < 1 || pos>len) {
printf("pos值不合法...\n");
return;
}
//依旧先查找
ListNode* PosNode = Search_pos_elem(pphead, pos);
if (PosNode == NULL) {
printf("该位置没有元素,无法修改...\n");
return;
}
PosNode->data = data;
}
//现在是打印链表函数
void my_printf(ListNode* phead) {
//assert(phead);
if (phead == NULL)
{
printf("当前链表为空...\n");
return;
}
ListNode* pcur = phead;
while (pcur != NULL) {
printf("%d ", pcur->data);
pcur = pcur->next;
}
printf("\n");
}
//现在是查找目标元素函数
void Search_elem(ListNode** pphead, Elemtype data) {
assert(pphead);
ListNode* pcur = *pphead;
int count = 0;
int flag = 0;
while (pcur != NULL) {
count++;
if (pcur->data == data) {
printf("找到了!在第%d个位置\n", count);
flag = 1;
break;
}
pcur = pcur->next;
}
if (flag == 0) {
printf("没找到你想要的元素...\n");
}
}
//现在是销毁链表函数
void Destory_ListNode(ListNode** pphead) {
assert(pphead);
ListNode* pcur = *pphead;
while (pcur != NULL) {
ListNode* delet = pcur;
pcur = pcur->next;
free(delet);
delet = NULL;
}
*pphead = NULL;
pcur = NULL;
}
//打印菜单
void printf_menu() {
printf("=========================================================================\n");
printf("有以下操作:\n");
printf("插入操作:\n");
printf("1.头部插入 2.尾部插入 3.pos位置之前插入 4.pos位置之后插入\n");
printf("删除操作:\n");
printf("5.头部删除 6.尾部删除 7.pos位置删除\n");
printf("\n");
printf("8.查找元素 9.修改元素\n");
printf("=========================================================================\n");
printf("\n");
}
//现在是主函数
int main() {
ListNode* phead = NULL;
Init_ListNode(&phead);
ListNode* pphead = &phead;
int choose = 0;
do {
system("cls");
printf_menu();
printf("当前的链表为:\n");
my_printf(phead);
printf("请输入你的选择(按-1退出程序):\n");
scanf("%d", &choose);
switch (choose) {
case 1: {
printf("请输入你想输入元素的个数:\n");
int num = 0;
scanf("%d", &num);
Elemtype data = 0;
printf("请输入你想输入的元素:\n");
for (int i = 0; i < num; i++) {
scanf("%d", &data);
Push_Front(pphead, data);
}
printf("插入成功!!!\n");
Sleep(2000);
break;
}
case 2: {
printf("请输入你想输入元素的个数:\n");
int num = 0;
scanf("%d", &num);
Elemtype data = 0;
printf("请输入你想输入的元素:\n");
for (int i = 0; i < num; i++) {
scanf("%d", &data);
Push_Back(pphead, data);
}
printf("插入成功!!!\n");
Sleep(2000);
break;
}
case 3: {
printf("请输入你想插入的位置:\n");
int pos = 0;
scanf("%d", &pos);
printf("请输入你想插入的元素:\n");
Elemtype data = 0;
scanf("%d", &data);
Push_pos_Front(pphead, data, pos);
printf("插入成功!!!\n");
Sleep(2000);
break;
}
case 4: {
printf("请输入你想插入的位置:\n");
int pos = 0;
scanf("%d", &pos);
printf("请输入你想插入的元素:\n");
Elemtype data = 0;
scanf("%d", &data);
Push_pos_Back(pphead, data, pos);
printf("插入成功!!!\n");
Sleep(2000);
break;
}
case 5: {
Pop_Front(pphead);
printf("删除成功!\n");
Sleep(2000);
break;
}
case 6: {
Pop_Back(pphead);
printf("删除成功!\n");
Sleep(2000);
break;
}
case 7: {
printf("请输入你想要删除元素的位置:\n");
int pos = 0;
scanf("%d", &pos);
Pop_pos(pphead, pos);
printf("删除成功!\n");
Sleep(2000);
break;
}
case 8: {
printf("请输入你想要查找的元素:\n");
Elemtype data = 0;
scanf("%d", &data);
Search_elem(pphead, data);
Sleep(2000);
break;
}
case 9: {
printf("请输入你想要修改之后的元素:\n");
Elemtype data = 0;
scanf("%d", &data);
printf("请输入想要改变的位置:\n");
int pos = 0;
scanf("%d", &pos);
Change_elem_pos(pphead, pos, data);
printf("修改成功!!!\n");
Sleep(2000);
break;
}
case -1: {
printf("正在退出程序...\n");
Sleep(1000);
printf("退出成功!!!\n");
Sleep(2000);
break;
}
default: {
printf("choose值不合法,请重新输入:\n");
Sleep(2000);
break;
}
}
} while (choose != -1);
Destory_ListNode(pphead);
pphead = NULL;
return 0;
}
以上就是我对单链表所有内容的分享了,感谢大佬们的阅读~~~
文章是自己写的哈,有啥描述不对的、不恰当的地方,恳请大佬指正,看到后会第一时间修改,感谢您的阅读。