数据结构 链表的构建——增删
/*************************************************
*
* file name:LkList.c
* author :momolyl@126.com
* date :2024/04/22
* function :通过构建链表学习顺序存储
* note :None
*
* CopyRight (c) 2024 momolyl@126.com All Right Reseverd
*
**************************************************/
#include <stdbool.h>
#include <stdlib.h>
/*************************************************
*
* func name :
* func function :
* func parameter:
*
*
* return :None
* note :None
* func author :momolyl@126.com
* date :2024/04/19
* version :V1.0
**************************************************/
// 结构体用于构建链表节点(数据域+指针域)
typedef int Datatype_t;
typedef struct LkList
{
Datatype_t Data;
struct LkList *Next;
} LkList_t;
// 创建一个空链表,使用头节点
LkList_t *LkList_Create(void)
{
LkList_t *Head = (LkList_t *)calloc(1, sizeof(LkList_t)); // 为头节点申请内存,并错误处理
if (NULL == Head)
{
perror("calloc memory for LkList if failed!\n");
exit(-1);
}
Head->Next = NULL; // 将头节点的指针域指向NULL
return Head; // 返回头节点的地址
}
// 创建一个新节点,并对新节点初始化(数据域+指针域)
LkList_t *LkList_NewNode(Datatype_t data)
{
LkList_t *NewNode = (LkList_t *)calloc(1, sizeof(LkList_t)); // 为新节点申请一个地址,
NewNode->Data = data; // 初始化数据域
NewNode->Next = NULL; // 初始化指针域
return NewNode;
}
// 向链表中头插一个新节点
void LkList_HeadAdd(LkList_t *Head, Datatype_t data)
{
LkList_t *NewNode = LkList_NewNode(data);
if (NULL == Head->Next) // 判断链表是否为空
{
// 链表为空
Head->Next = NewNode;
return;
}
// 2.2链表非空
{
NewNode->Next = Head->Next;
Head->Next = NewNode;
}
}
// 向链表中尾插一个新节点
void LkList_TailAdd(LkList_t *Head, Datatype_t data)
{
LkList_t *NewNode = LkList_NewNode(data);
if (NULL == Head->Next) // 判断链表是否为空
{
// 链表为空
Head->Next = NewNode;
return;
}
// 2.2链表非空
LkList_t *Phead = Head; // 备份链表的头节点地址
while (Phead->Next) // 遍历节点找到尾端
{
Phead = Phead->Next;
}
// 在尾端插入新节点
{
Phead = NewNode; // 将新节点的地址赋值给最后一个节点的指针域
}
}
// 在链表中头删一个节点
bool LkList_HeadDel(LkList_t *Head)
{
// 判断链表是否为空
if (Head->Next)
return false; // 为空则删除失败
LkList_t *FirstNode = Head->Next; // 备份首节点地址
Head->Next = Head->Next->Next; // 将首节点的直接后继节点的地址赋值给头节点的指针域
Head->Next->Next = NULL; // 断开首节点与其直接后继节点的链接
free(FirstNode); // 释放原首节点的地址,并将指针指向NULL
FirstNode = NULL;
return true;
}
// 在链表中尾删一个节点
bool LkList_HeadDel(LkList_t *Head)
{
if (Head->Next) // 判断链表是否为空
return false; // 为空则删除失败
LkList_t *Phead = Head; // 备份链表的头节点地址
while (Phead->Next) // 遍历节点找到尾端
{
Phead = Phead->Next;
}
LkList_t *LastNode = Phead; // 备份尾节点地址
Phead = NULL; // 将尾节点的直接前驱指针域指向NULL
free(LastNode); // 释放尾节点的地址
LastNode = NULL; // 将尾节点的指针指向NULL
return true;
}
// 根据节点的数据域指定删除一个节点(首尾节点的情况还没考虑到,太困了肝不动了4.23,明天再优化)
bool LkList_AppointDel(LkList_t *Head, Datatype_t data)
{
if (Head->Next) // 判断链表是否为空
return false; // 为空则删除失败
LkList_t *Phead = Head; // 备份链表的头节点地址
while (Phead->Next == data) // 遍历节点找到指定数据的节点的直接前驱地址
{
Phead = Phead->Next;
}
LkList_t *AppointNode = Phead; // 备份指定数据的节点的直接前驱地址
Phead->Next = Phead->Next->Next; // 将指定节点的直接前驱指针域指向定节点的直接后继节点的地址
AppointNode->Next->Next = NULL; // 将指定节点的指针域指向NULL
free(AppointNode->Next); // 释放指定节点的地址
AppointNode->Next = NULL; // 将指定节点的指针指向NULL
return true;
}
int main(void)
{
LkList_Create();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!