单向链表:

一:链表的定义
在这里插入图片描述
链表节点的定义:
在这里插入图片描述
二:静态链表


#include <stdio.h>    
typedef struct stu  {      
//数据域      
int num;      
char name[32];      
float score;        
//指针域      
//next保存下一个节点的地址 编号      
struct stu *next;  }STU;  
void test01()  {      
STU data1={100,"lucy",89.1,NULL};      
STU data2={101,"lucy1",89.1,NULL};      
STU data3={102,"lucy2",89.1,NULL};      
STU data4={103,"lucy3",89.1,NULL};        
//链表头      
STU *head = &data1;      
data1.next = &data2;      
data2.next = &data3;      
data3.next = &data4;        
//遍历      
STU *pb = head;      
while(pb != NULL)      
{          
printf("%d %s %f\n", pb->num, pb->name,pb->score);          
//去往下一个节点          
pb = pb->next;      
}    
}  
int main(int argc, char const *argv[])  
{      
test01();      
return 0;  
} 

三:链表的插入操作
1,在链表头部插入节点

```c

STU* insert_link(STU *head, STU tmp)  {      
//1、为插入的节点 申请 堆区空间      
STU *pi = (STU *)calloc(1,sizeof(STU));      
//2、将tmp的数据 赋值到 *pi中      
*pi = tmp;      
//将pi->next赋值为NULL      
pi->next = NULL;        
//3、判断链表是否为NULL      
if(head == NULL)//链表不存在      
{          
head = pi;          
//return head;      
}      
else//链表存在      {          
//让pi->next指向旧的head节点          
pi->next = head;            
//更新头节点 信息          
head = pi;          
//return head;      
}        
return head;  
}  
```

2,在链表尾部插入节点

```c

//尾部插入  
STU* insert_link(STU *head, STU tmp)  
{      
//1、为带插入的节点 申请空间      
STU *pi = (STU *)calloc(1,sizeof(STU));      
//2、将tmp的数据 赋值给*pi      
*pi = tmp;      
pi->next = NULL;        
//3、判断链表 是否存在      
if(head == NULL)//不存在     
{          
head = pi;          
//return head;      
}      
else//存在      
{          
//寻找尾节点          
STU *pb = head;          
while(pb->next != NULL)          
{              
pb = pb->next;          
}            
//将尾节点的 指针域next 指向新的pi节点          
pb->next = pi;          
//return head;      
}      
return head;  
}  
```

3,有序插入链表节点


//链表的有序插入  
STU* insert_link(STU *head, STU tmp)  {      
//1、为待插入的节点 申请空间      
STU *pi = (STU *)calloc(1,sizeof(STU));      
//2、将tmp的数据 赋值给*pi      
*pi = tmp;      
pi->next = NULL;        
//判断链表 是否为空      
if(head == NULL)//为NULL     
{          
head = pi;          
return head;      
}      
else//不为空      
{             
//逐个节点寻找插入点的位置          
STU *pf = head, *pb = head;          
//pb->num < pi->num 按照num从小-->大排          
//pb->next != NULL 防止链表 查询越界          
while((pb->num < pi->num) && (pb->next != NULL))          
{              
//pf记录pb移动之前的位置              
pf = pb;              
pb往下一个节点移动              
pb = pb->next;         
}            
//判断插入点的位置(前  中  尾)          
if(pb->num >= pi->num)//前 中          
{              
if(pb == head)//头部前 插入              
{                 
 pi->next = head;//保存旧链表的头地址                  
 head = pi;//跟新新链表头地址              
 }              
 else//中部 插入              
 {                  
 pf->next = pi;                  
 pi->next = pb;              
 }          
 }          
 else if(pb->next == NULL)//尾部          
 {              
 pb->next = pi;          
 }      
 }            
return head;//重要  
} 

四:链表的遍历


void print_link(const STU *head)  
{      
//1、判断链表 是否存在      
if(head == NULL)//不存在      
{         
printf("链表不存在\n");          
return;      
}      
else//存在      
{          
const STU *pb = head;          
while(pb != NULL)          
{              
printf("num=%d, name=%s, score=%f\n", pb->num, pb->name, pb->score);              
pb = pb->next;          
}      
}  
}  

五:链表的查找


STU* find_link(STU *head, char *name)  {      
//1、判断链表是否存在      
if(head == NULL)      
{          
printf("链表不存在\n");          
return NULL;      
}      
else//链表存在      
{          
//逐个节点查询          
STU *pb = head;          
while((strcmp(pb->name, name) != 0) && (pb->next != NULL))          
{              
pb = pb->next;          
}            
//判断越界 还是找到相应的节点          
if(strcmp(pb->name, name) == 0)//找到          
{              
return pb;          
}          
else if(pb->next == NULL)//未找到          
{              
printf("未找到姓名为%s的节点信息\n", name);              
return NULL;          
}      
}      
return NULL;  
}  

六:删除链表指定节点


STU* delete_link(STU *head,float score)  
{         
//判断链表是否存在      
if(head == NULL)//不存在      
{          
printf("链表不存在\n");          
return head;      
}      
else//存在      
{          
//逐个节点查询删除点          
STU *pf = head, *pb = head;          
while((pb->score != score) && (pb->next != NULL))          
{              
pf = pb;              
pb = pb->next;          
}            
if(pb->score == score)//找到删除点          
{              
if(pb ==head)//删除头节点              
{                  
head = head->next;              
}              
else//删除中、尾节点              
{                  
pf->next = pb->next;              
}                
//释放要删除的节点              
free(pb);              
printf("节点删除成功\n");              
return head;          
}          
else//未找到删除点          
{              
printf("未找到删除点\n");              
return head;//重要          
}      
}            
return head;  
}  

七:释放整个链表


STU *free_link(STU *head)  
{      
//判断链表 是否存在      
if(head == NULL)      
{          
printf("链表不存在\n");          
return head;      
}      
else//存在      
{          
STU *pb = head;          
//逐个节点释放          
while(pb != NULL)          
{              
//head记录下一个节点的位置              
head = head->next;              
//释放pb              
free(pb);              
//更新pb的位置              
pb = head;          
}          
return head;      
}      
return head;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小卡丘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值