C语言实现链表增、删、改、查基本操作
//C语言实现链表增、删、改、查基本操作
//作者:理想
//日期:2021.04.25
#include <stdio.h> //包含头文件,调用I/O函数
#include <stdlib.h> // 调用malloc函数
typedef struct Node{
int Data; // 节点数据域
struct Node* Next; // 节点指针域
}Node; //创建自定义结构体并命名为Node
// 创建链表,返回头节点
Node* CreateList(){
// 动态分配内存,创建头节点
Node* HeadNode = (Node*)malloc(sizeof(Node));
//初始化头节点
HeadNode->Next = NULL;
//返回头节点
return HeadNode;
}
//创建节点
Node* CreateNode(int data){
// 动态分配内存,创建NEW节点
Node* NewNode = (Node*)malloc(sizeof(Node));
//初始化NEW节点
NewNode->Data = data; //注意避坑 -> 符左右不能有空格
NewNode->Next = NULL;
//返回新节点
return NewNode;
}
//插入节点(头插法)
Node* InsertNodeByHead(Node*head, int data){
//创建新节点
Node* NewNode = CreateNode(data);
//头插法将新节点插入链表第一个元素位置
NewNode->Next = head->Next;
//链表头指针指向第一个元素位置
head->Next = NewNode;
}
//遍历打印列表
void PrintList(Node* head){
//创建移动节点并指向链表首元素 用于遍历链表
Node* pMove = head->Next;
//链表判空
if (pMove == NULL){
printf("List is NULL!\n");
}
//条件循环:判断是否为链表尾元素 一直循环到链表末尾元素结束
while(pMove){
//打印节点数据
printf("%d\n",pMove->Data);
//移动节点至下一个
pMove = pMove -> Next;
}
printf("\n");
}
//删除指定节点
void RemoveNode(Node* head, int popdata){
//创建移动节点指向链表首元素 用于判断是否为要删除的节点
Node* popNode = head->Next;
//创建移动节点前一个节点指向移动节点前一个 用于记录删除节点的前一个节点
Node* popNodeFront = head;
//链表判空
if(popNode == NULL){
printf("ERR:List is NULL!")
} else{
//条件循环:判断移动节点数据是否为要删除的数据
while(popNode->Data != popdata){
//首先将当前节点存放到popNodeFront内,当前popNodeFront存放的是当前节点popNode
popNodeFront = popNode;
//注意:由于上一步骤已经将当前移动节点popNode存放至popNodeFront,所以将当前节点指向popNodeFront的下一节点即可
popNode = popNodeFront->Next;
// 注意:此处判断是否为链表结尾元素,由于前面已经将popNode指向下一节点,所以判断条件不能是popNode->Next == NULL
if(popNode == NULL){
printf("ERR:Not Found %d\n", popdata);
//注意:跳出循环
return; // break
}
}
// 注意:如果找到需要删除的节点后需跳出循环进行删除操作
//将当前节点前一个节点的指针域指向当前节点的下一个节点即可将此节点删除
popNodeFront->Next = popNode->Next;
//释放节点空间,避免造成内存垃圾
free(popNode);
}
}
// 查找指定节点
Node* SearchNode(Node* head,int seekdata){
//创建移动节点并指向链表首元素 用于遍历链表
Node* pMove = head->Next;
//链表判空
if (pMove == NULL){
printf("List is NULL!\n");
}
//条件循环: 判断是否为查询节点
while(pMove->Data != seekdata){
// 若不是需要查询的节点,移动至下一个节点
pMove = pMove->Next;
//判断是否为链表结尾节点
if(pMove == NULL){
//没找到哦
//printf("Not Frount %d\n", seekdata);
//注意:跳出循环
return pMove ; //break
}
}
//找到啦
//printf("%d Exsit The List!\n", seekdata);
return pMove;
}
//修改指定节点数据元素
void ModifyNode(Node* head,int origin, int update){
//查找节点
Node* SearchNode = SearchNode(head,origin);
if(SearchNode == NULL){
printf("ERR:Not Fount The Data In The List !\nModify failly\n");
}else{
//修改节点
//printf("%d\n", searchNode->Data);
SearchNode->Data = update;
printf("Modify Successly!\n");
PrintList(head);
}
}
void main(){
void InsertNodeByAppoint(Node* head,int frontdata,int data);
//创建链表头节点
Node* HeadNode = CreateList();
//插入节点元素
InsertNodeByHead(HeadNode,1);
InsertNodeByHead(HeadNode,2);
InsertNodeByHead(HeadNode,5);
//遍历打印链表
PrintList(HeadNode);
//删除指定节点8
RemoveNode(HeadNode,0);
PrintList(HeadNode);
SearchNode(HeadNode, 1);
Node* searchNode = SearchNode(HeadNode, 9);
if(searchNode == NULL){
printf("Not Frount\n");
}else{
printf("%d\n", SearchNode->Data);
}
ModifyNode(HeadNode,1,0);
InsertNodeByAppoint(HeadNode,20,8);
printf("hello world\n");
}
//指定位置插入节点 指定前一个节点元素
void InsertNodeByAppoint(Node* head,int frontdata,int data){
Node* NewNode = CreateNode(data);
//查找前节点
Node* FrontNode = SearchNode(head,frontdata);
if(FrontNode == NULL){
printf("ERR:Not Fount The Data In The List !\n Insert failly\n");
}else{
//插入节点
Node* BeforeNode = FrontNode->Next;
FrontNode->Next = NewNode;
NewNode->Next = BeforeNode;
printf("Insert Successly!\n");
PrintList(head);
}
}
阅读剩余
版权声明:
作者:理想
链接:https://www.imyjs.cn/archives/852
文章版权归作者所有,未经允许请勿转载。
THE END