C语言单向链表的创建和增删减查相关程序
单向链表增删减查程序学习设计和相关习题练习
单向链表的增删减查程序的设计
/******************************************************************
*
* file name: linkedlist.c
* author : 17666589210@136.com
* date : 2024/04/22
* function : 实现单向链表的创建、拆入、删除功能
* note : None
*
* CopyRight (c) 2023-2024 17666589210@136.com All Right Reseverd
*
*******************************************************************/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
//指的是单向链表中的结点有效数据类型,用户可以根据需要进行修改
typedef int DataType_t;
//构造链表的结点,链表中所有结点的数据类型应该是相同的
typedef struct LinkedList
{
DataType_t data; //结点的数据域
struct LinkedList *next; //结点的指针域
}LList_t;
/*************************************************************************
*
* func name: LList_Create
* author : 17666589210@136.com
* date : 2024/04/22
* function : 实现单向链表中的头结点创建
* note : None
*
* CopyRight (c) 2023-2024 17666589210@136.com All Right Reseverd
*
*************************************************************************/
//创建一个空链表,空链表应该有一个头结点,对链表进行初始化
LList_t * LList_Create(void)
{
//1.创建一个头结点并对头结点申请内存
LList_t *Head = (LList_t *)calloc(1,sizeof(LList_t));
if (NULL == Head)
{
perror("Calloc memory for Head is Failed");
exit(-1);
}
//2.对头结点进行初始化,头结点是不存储有效内容的!!!
Head->next = NULL;
//3.把头结点的地址返回即可
return Head;
}
/*************************************************************************
*
* func name: LList_NewNode
* author : 17666589210@136.com
* date : 2024/04/22
* function : 实现单向链表的结点创建
* note : None
*
* CopyRight (c) 2023-2024 17666589210@136.com All Right Reseverd
*
*************************************************************************/
//创建新的结点,并对新结点进行初始化(数据域 + 指针域)
LList_t * LList_NewNode(DataType_t data)
{
//1.创建一个新结点并对新结点申请内存
LList_t *New = (LList_t *)calloc(1,sizeof(LList_t));
if (NULL == New)
{
perror("Calloc memory for NewNode is Failed");
return NULL;
}
//2.对新结点的数据域和指针域进行初始化
New->data = data;
New->next = NULL;
return New;
}
/*************************************************************************
*
* func name: LList_HeadInsert
* author : 17666589210@136.com
* date : 2024/04/22
* function : 实现单向链表结点头插
* note : None
*
* CopyRight (c) 2023-2024 17666589210@136.com All Right Reseverd
*
*************************************************************************/
//头插
bool LList_HeadInsert(LList_t *Head,DataType_t data)
{
//1.创建新的结点,并对新结点进行初始化
LList_t *New = LList_NewNode(data);
if (NULL == New)
{
printf("can not insert new node\n");
return false;
}
//2.判断链表是否为空,如果为空,则直接插入即可
if (NULL == Head->next)
{
Head->next = New;
return true;
}
//3.如果链表为非空,则把新结点插入到链表的头部
New->next = Head->next;
Head->next = New;
return true;
}
/*************************************************************************
*
* func name: LList_TailInsert
* author : 17666589210@136.com
* date : 2024/04/22
* function : 实现单向链表结点尾插
* note : None
*
* CopyRight (c) 2023-2024 17666589210@136.com All Right Reseverd
*
*************************************************************************/
//尾插
bool LList_TailInsert(LList_t* Head, DataType_t data)
{
//1.创建新的结点,并对新结点进行初始化
LList_t* New = LList_NewNode(data);
if (NULL == New)
{
printf("can not insert new node\n");
return false;
}
//2.判断链表是否为空,如果为空,则退出
if(NULL == Head->next)
{
return false;
}
//对链表的头文件的地址进行备份
LList_t* Phead = Head;
//首结点
while (Phead->next)
{
//把头的直接后继作为新的头结点
Phead = Phead->next;
}
Phead->next = New;
New->next = NULL;
return true;
}
/*************************************************************************
*
* func name: LList_DestInsert
* author : 17666589210@136.com
* date : 2024/04/22
* function : 实现单向链表指定位置插入结点
* note : None
*
* CopyRight (c) 2023-2024 17666589210@136.com All Right Reseverd
*
*************************************************************************/
//任意插
bool LList_DestInsert(LList_t* Head, DataType_t dest, DataType_t data)
{
//1.创建新的结点,并对新结点进行初始化
LList_t* New = LList_NewNode(data);
if (NULL == New)
{
printf("can not insert new node\n");
return false;
}
//2.判断链表是否为空,如果为空,则直接插入即可
if (NULL == Head->next)
{
return false
}
//对链表的头文件的地址进行备份
LList_t* Phead1 = Head;
LList_t* phead2 = Head;
for (int i = 0; i < dest; i++)
{
//目标前驱地址
Phead1 = Phead1->next;
}
for (int j = 0; j <= dest; j++)
{
//目标后继地址
Phead2 = Phead2->next;
}
New->next = Phead2;
Pheadl-> = New;
return true;
}
/*************************************************************************
*
* func name: LList_HeadDele
* author : 17666589210@136.com
* date : 2024/04/22
* function : 实现单向链表头结点删除
* note : None
*
* CopyRight (c) 2023-2024 17666589210@136.com All Right Reseverd
*
*************************************************************************/
//头删
bool LList_HeadDele(LList_t* Head)
{
//1.判断链表是否为空,如果为空,则直接返回
if (NULL == Head->next)
{
return false;
}
LList_t* Phead = Head->next;
//2.如果链表为非空,则删除头结点
Head->next = Head->next->next;
Head->next->next == NULL;
free(Phead);
return true;
}
/*************************************************************************
*
* func name: LList_TailDele
* author : 17666589210@136.com
* date : 2024/04/22
* function : 实现单向链表尾结点删除
* note : None
*
* CopyRight (c) 2023-2024 17666589210@136.com All Right Reseverd
*
*************************************************************************/
//尾删
bool LList_TailDele(LList_t* Head)
{
//1.判断链表是否为空,如果为空,则直接返回
if (NULL == Head->next)
{
return false;
}
//对链表的头文件的地址进行备份
LList_t* Phead1 = Head;
LList_t* Phead2 = Head;
//首结点开始进行遍历
int count = 0;
while (Phead1->next)
{
//记录前驱地址
Phead1 = Phead1->next;
//记录循环次数
count++;
}
for (int i = 0; i < count - 1; i++)
{
//记录后继地址
Phead2 = Phead2->next;
}
Phead2->next = NULL;
free(Phead1);
return true;
}
/*************************************************************************
*
* func name: LList_DestDele
* author : 17666589210@136.com
* date : 2024/04/22
* function : 实现单向链表指定数值的结点删除
* note : None
*
* CopyRight (c) 2023-2024 17666589210@136.com All Right Reseverd
*
*************************************************************************/
//任意删
bool LList_DestDele(LList_t* Head, DataType_t data)
{
//1.判断链表是否为空,如果为空,则直接返回
if (NULL == Head->next)
{
return false;
}
//对链表的头文件的地址进行备份
LList_t* Phead1 = Head;
LList_t* Phead2 = Head;
//首结点开始进行遍历
int count = 0;
while (Phead1->next)
{
Phead1 = Phead1->next;
count++;
//找到data的值所在位置
if (data == Phead1->data)
{
break;
}
}
for (int i = 0; i < count + 1; i++)
{
Phead2 = Phead2->next;
}
Phead1->next = Phead2->next;
Phead2-> = NULL;
free(Phead2);
return true;
}
/*************************************************************************
*
* func name: LList_Print
* author : 17666589210@136.com
* date : 2024/04/22
* function : 实现输出所有单向链表结点中的数据
* note : None
*
* CopyRight (c) 2023-2024 17666589210@136.com All Right Reseverd
*
*************************************************************************/
//遍历输出
void LList_Print(LList_t* Head)
{
//对链表的头文件的地址进行备份
LList_t* Phead = Head;
//首结点
while (Phead->next)
{
//把头的直接后继作为新的头结点
Phead = Phead->next;
//输出头结点的直接后继的数据域
printf("data = %d\n", Phead->data);
}
}
int main(int argc, char const *argv[])
{
return 0;
}
单向链表的习题一
- 删除单链表L(有头结点)中的一个最小值结点
/*************************************************************************
*
* func name: LList_Print
* author : 17666589210@136.com
* date : 2024/04/22
* function : 实现输出所有单向链表结点中的数据
* note : None
*
* CopyRight (c) 2023-2024 17666589210@136.com All Right Reseverd
*
*************************************************************************/
bool LList_DeleMin(LList_t* Head)
{
//1.判断链表是否为空,如果为空,则直接返回
if (NULL == Head->next)
{
return false;
}
if(NULL==Head->next->next)//只有一个数据元素情况时
{
Head->next = NULL;
return true;
}
//对链表的头文件的地址进行备份
LList_t* Phead1 = Head;
LList_t* Phead2 = Head;
int min = Head->data;//假设第一个数据为最小值
//首结点开始进行遍历
int count = 0,temp = 0;
while (Phead1->next)
{
Phead1 = Phead1->next; //遍历到尾的地址
temp++;
//找到data的值所在位置
if (min>=Phead1->data)
{
min = Phead1->data;
count = temp;
}
}
for (int i = 0; i < count - 1; i++)
{
Phead2 = Phead2->next;//最下值的前一个结点的地址
}
LList_t* P = Phead2->next;
Phead2->next= Phead2->next->next;
P = NULL;
free(P);
return true;
}
单向链表的习题二
- 假设该链表只给出了头指针 head。在不改变链表的前提下,请设计一个尽可能高效的算法,
- 查找链表中倒数第k(k为正整数个位置上的结点。若查找成功,算法输出该结点的data值,并返回1,否则,只返回0。
/*************************************************************************
*
* func name: LList_FindDataPut
* author : 17666589210@136.com
* date : 2024/04/22
* function : 实现查找链表中倒数第k个位置上的结点的值
* note : None
*
* CopyRight (c) 2023-2024 17666589210@136.com All Right Reseverd
*
*************************************************************************/
int LList_FindDataPut(LList_t* Head,unsigned int k)
{
int count = 0;
LList_t* Phead1 = Head;
LList_t* Phead2 = Head;
while (Phead1->next)
{
Phead1 = Phead1->next; //遍历到尾的地址
count++;
}
if (k > count) //找不到的情况
{
printf("can not find K-th to last data = %d\n")
return 0;
}
for (int i = 0; i < count - k; i++)
{
Phead2 = Phead2->next;//找到倒数第k个的地址
}
printf("K-th to last data = %d\n", Phead2->data);//输出k下所在的数据
return 1;
}
···
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现