链表
是一种物理存储上非连续,数据元素的逻辑顺序通过链表中的指针链接次序,实现的一种线性存储结构
特点:
链表由一系列节点(链表中每一个元素称为节点)组成,节点在运行时动态生成(malloc),每个节点包括两个部分:
1、存储数据元素的数据域
2、存储下一个节点地址的指针域
链表的构成:
链表由一个个节点构成,每个节点一般采用结构体的形式组织
typedef struct 顺序表结构体的名字
{
//存放有效数据的一个数组,数组类型依据程序员的实际需求定义
//记录保存当前数组的最后一个有效成员
}
例如
typedef struct student
{
int num;
char name[20];
struct student *next;
}STU;
链表节点分为两个域:
数据域:存放各种实际的数据,如num,score等
指针域:存放下一个节点的首地址,如next等;
实现链表的遍历和创建
#include<stdio.h>
#include<stdlib.h>
//链表创建
typedef struct student
{ //数据域
int num;
int score;
char name[20];
struct student *next; //指针域
}STU;
void link_print(STU *head)//遍历链表,打印链表中的数据
{
STU *p_mov = head;
while(p_mov != NULL)
{
printf("%d %d %s ",p_mov->num,p_mov->score,p_mov->name);//打印数据
p_mov = p_mov->next;
}
}
void link_create_head(STU **p_head,STU *p_new) //创建链表,将传入的值放到数据的后面
{
STU *p_mov = *p_head; //把链表的第一个值传给p_mov
if(*p_head == NULL)// 如果链表为空,当第一次加入链表
{
*p_head = p_new;
p_new->next =NULL; //新来节点的下一节点置为空
}
else //第二次加入链表
{
while (p_mov->next != NULL)
{
p_mov =p_mov->next; //如果不为空,不断判断,找到最后一个值
}
p_mov->next = p_new; //找到后将值传入下一个节点
p_new ->next = NULL;
}
}
int main()
{
STU *head = NULL, *p_new = NULL;//对head首个节点地址初始化为0,p_new记录新节点地址
int num,i;
printf("请输入链表初始化个数\n");
scanf("%d",&num);
for(i = 0;i < num;i++)
{
p_new = ( STU *)malloc(sizeof(STU));//每次循环,malloc申请一个新的节点
printf("请输入学号、分数、名字\n");//给新节点赋值
scanf("%d %d %s",&p_new->num,&p_new->score,&p_new->name);
link_create_head(&head,p_new); //将新节点加入链表,将head的地址传给函数,地址对值进行操作
}
link_print(head);
}
实现链表中对数据的查找
#include<stdio.h>
#include<stdlib.h>
//链表创建
typedef struct student
{ //数据域
int num;
int score;
char name[20];
struct student *next; //指针域
}STU;
STU *link_search_num(STU *head,int num)//寻找节点中是否与num相同的值
{
STU *p_mov = head;
while(p_mov != NULL) //判断链表是否为空
{
if(p_mov->num == num) //寻找节点中的值是否和num相同
{
return p_mov;//如果找到了就返回他的地址
}
p_mov = p_mov->next;
}
return NULL;
}
void link_print(STU *head)//遍历链表,打印链表中的数据
{
STU *p_mov = head;
while(p_mov != NULL)
{
printf("%d %d %s ",p_mov->num,p_mov->score,p_mov->name);//打印数据
p_mov = p_mov->next;
}
}
void link_create_head(STU **p_head,STU *p_new) //创建链表,将传入的值放到数据的后面
{
STU *p_mov = *p_head; //把链表的第一个值传给p_mov
if(*p_head == NULL)// 如果链表为空,当第一次加入链表
{
*p_head = p_new;
p_new->next =NULL; //新来节点的下一节点置为空
}
else //第二次加入链表
{
while (p_mov->next != NULL)
{
p_mov =p_mov->next; //如果不为空,不断判断,找到最后一个值
}
p_mov->next = p_new; //找到后将值传入下一个节点
p_new ->next = NULL;
}
}
int main()
{
STU *head = NULL, *p_new = NULL,*pd = NULL;//对head首个节点地址初始化为0,p_new记录新节点地址
int num,i;
printf("please input the link number\n");
scanf("%d",&num);
for(i = 0;i < num;i++)
{
p_new = ( STU *)malloc(sizeof(STU));//每次循环,malloc申请一个新的节点
printf("please input you num , score, name\n");//给新节点赋值
scanf("%d %d %s",&p_new->num,&p_new->score,&p_new->name);
link_create_head(&head,p_new); //将新节点加入链表,将head的地址传给函数,地址对值进行操作
}
while (1)
{
printf("please input you search number:\n");
scanf("%d",&num);
pd = link_search_num(head,num);
if(pd != NULL)
{
printf("find the number %d %d %s\n",pd->num,pd->score,pd->name);//找到节点的
}
else
{
printf("not find the same number\n");
}
}
// link_print(head);
}
链表的释放
#include<stdio.h>
#include<stdlib.h>
//链表创建
typedef struct student
{ //数据域
int num;
int score;
char name[20];
struct student *next; //指针域
}STU;
STU *link_search_num(STU *head,int num)//寻找节点中是否与num相同的值
{
STU *p_mov = head;
while(p_mov != NULL) //判断链表是否为空
{
if(p_mov->num == num) //寻找节点中的值是否和num相同
{
return p_mov;//如果找到了就返回他的地址
}
p_mov = p_mov->next;
}
return NULL;
}
void link_print(STU *head)//遍历链表,打印链表中的数据
{
STU *p_mov = head;
while(p_mov != NULL)
{
printf("%d %d %s ",p_mov->num,p_mov->score,p_mov->name);//打印数据
p_mov = p_mov->next;
}
}
void link_create_head(STU **p_head,STU *p_new) //创建链表,将传入的值放到数据的后面
{
STU *p_mov = *p_head; //把链表的第一个值传给p_mov
if(*p_head == NULL)// 如果链表为空,当第一次加入链表
{
*p_head = p_new;
p_new->next =NULL; //新来节点的下一节点置为空
}
else //第二次加入链表
{
while (p_mov->next != NULL)
{
p_mov =p_mov->next; //如果不为空,不断判断,找到最后一个值
}
p_mov->next = p_new; //找到后将值传入下一个节点
p_new ->next = NULL;
}
}
void link_free(STU **p_head)//链表的释放
{
STU *pd,*pf;
pd = pf = *p_head;
while(pf != NULL)
{
pd = pf->next; //pd记录下一个节点地址
free(pf);//释放pf
pf = pd;
}
*p_head =NULL;//将首地址置为空
}
int main()
{
STU *head = NULL, *p_new = NULL,*pd = NULL;//对head首个节点地址初始化为0,p_new记录新节点地址
int num,i;
printf("please input the link number\n");
scanf("%d",&num);
for(i = 0;i < num;i++)
{
p_new = ( STU *)malloc(sizeof(STU));//每次循环,malloc申请一个新的节点
printf("please input you num , score, name\n");//给新节点赋值
scanf("%d %d %s",&p_new->num,&p_new->score,&p_new->name);
link_create_head(&head,p_new); //将新节点加入链表,将head的地址传给函数,地址对值进行操作
}
while (1)
{
printf("please input you search number:\n");
scanf("%d",&num);
pd = link_search_num(head,num);
if(pd != NULL)
{
printf("find the number %d %d %s\n",pd->num,pd->score,pd->name);//找到节点的
}
else
{
printf("not find the same number\n");
}
}
// link_print(head);
}
链表删除节点:
1、链表为空
不用查找,没有你要删除的节点
2、链表不为空
2.1找到的节点是头节点
2.2找到的节点不是头节点
2.3没有找到要删除的节点
不用删除
#include<stdio.h>
#include<stdlib.h>
//链表创建
typedef struct student
{ //数据域
int num;
int score;
char name[20];
struct student *next; //指针域
}STU;
STU *link_search_num(STU *head,int num)//寻找节点中是否与num相同的值
{
STU *p_mov = head;
while(p_mov != NULL) //判断链表是否为空
{
if(p_mov->num == num) //寻找节点中的值是否和num相同
{
return p_mov;//如果找到了就返回他的地址
}
p_mov = p_mov->next;
}
return NULL;
}
void link_print(STU *head)//遍历链表,打印链表中的数据
{
STU *p_mov = head;
while(p_mov != NULL)
{
printf("%d %d %s ",p_mov->num,p_mov->score,p_mov->name);//打印数据
p_mov = p_mov->next;
}
}
void link_create_head(STU **p_head,STU *p_new) //创建链表,将传入的值放到数据的后面
{
STU *p_mov = *p_head; //把链表的第一个值传给p_mov
if(*p_head == NULL)// 如果链表为空,当第一次加入链表
{
*p_head = p_new;
p_new->next =NULL; //新来节点的下一节点置为空
}
else //第二次加入链表
{
while (p_mov->next != NULL)
{
p_mov =p_mov->next; //如果不为空,不断判断,找到最后一个值
}
p_mov->next = p_new; //找到后将值传入下一个节点
p_new ->next = NULL;
}
}
void link_delete(STU **p_head, int num)
{
STU *pd,*pf;
pd =*p_head;
if(*p_head == NULL)//判断首节点是否为节点
{
printf("this is the link is NULL\n");
}
else//如果不是空节点
{
while(pd->num != num && pd->next != NULL )//判断从第一个节点开始的数和要查找的数是否相等,并且不是最后一个节点
{
pf = pd;//保存一下pd的位置
pd = pd->next; //不断的将下一个节点数据传递给pd,循环遍历一遍,没有做删除
}
if(pd->num == num)//如果找到相同的数据
{
if(pd == *p_head)//如果是首节点
{
*p_head = pd->next;//则将首节点的数据用下一个节点地址中的数据覆盖
free(pd);//因为记录pd记录了首节点
}
else//如果不是首节点
{
pf->next = pd->next;//将位置指向下一个节点,将下下一个数据传递给上一个节点
free(pd);
}
}
else//没有找到要删除的节点
{
printf("don't found the num\n");
}
}
}
void link_free(STU **p_head)//链表的释放
{
STU *pd,*pf;
pd = pf = *p_head;
while(pf != NULL) //记录首地址是否为空
{
pd = pf->next; //pd记录下一个节点地址
free(pf);//释放pf
pf = pd;
}
*p_head =NULL;//将首地址置为空
}
int main()
{
STU *head = NULL, *p_new = NULL,*pd = NULL;//对head首个节点地址初始化为0,p_new记录新节点地址
int num,i;
printf("please input the link number\n");
scanf("%d",&num);
for(i = 0;i < num;i++)
{
p_new = ( STU *)malloc(sizeof(STU));//每次循环,malloc申请一个新的节点
printf("please input you num , score, name\n");//给新节点赋值
scanf("%d %d %s",&p_new->num,&p_new->score,&p_new->name);
link_create_head(&head,p_new); //将新节点加入链表,将head的地址传给函数,地址对值进行操作
}
while (1)
{
printf("please input you search number:\n");
scanf("%d",&num);
if(num == 0)
{
break;
}
pd = link_search_num(head,num);
if(pd != NULL)
{
printf("find the number %d %d %s\n",pd->num,pd->score,pd->name);//找到节点的
}
else
{
printf("not find the same number\n");
}
}
link_print(head);
while (1)
{
printf("please iuput you delete num\n");
scanf("%d",&num);
link_delete(&head,num);//传入你要删除的链表首节点的地址,还有数字
link_print(head);
}
}
按num从小到大 插入一个节点
一、链表为空
要插入节点就是头节点
二、链表不为空
在链表中找一个节点num,比要插入的节点的num大
插在找到的节点前面
1、找到了一个节点的num,比要插入的节点的num大
1.1找到的节点你是头节点
插在头节点的前面
1.2找到的节点不是头节点
插在普通节点的前面
2、没有找到一个节点的num,比要插入的节点的num大,即
2.1要插入的节点的num最大
则插在最后面
#include<stdio.h>
#include<stdlib.h>
//链表创建
typedef struct student
{ //数据域
int num;
int score;
char name[20];
struct student *next; //指针域
}STU;
STU *link_search_num(STU *head,int num)//寻找节点中是否与num相同的值
{
STU *p_mov = head;
while(p_mov != NULL) //判断链表是否为空
{
if(p_mov->num == num) //寻找节点中的值是否和num相同
{
return p_mov;//如果找到了就返回他的地址
}
p_mov = p_mov->next;
}
return NULL;
}
void link_print(STU *head)//遍历链表,打印链表中的数据
{
STU *p_mov = head;
while(p_mov != NULL)
{
printf("%d %d %s\n ",p_mov->num,p_mov->score,p_mov->name);//打印数据
p_mov = p_mov->next;
}
}
void link_create_head(STU **p_head,STU *p_new) //创建链表,将传入的值放到数据的后面
{
STU *p_mov = *p_head; //把链表的第一个值传给p_mov
if(*p_head == NULL)// 如果链表为空,当第一次加入链表
{
*p_head = p_new;
p_new->next =NULL; //新来节点的下一节点置为空
}
else //第二次加入链表
{
while (p_mov->next != NULL)
{
p_mov =p_mov->next; //如果不为空,不断判断,找到最后一个值
}
p_mov->next = p_new; //找到后将值传入下一个节点
p_new ->next = NULL;
}
}
void link_delete(STU **p_head, int num)
{
STU *pd,*pf;
pd =*p_head;
if(*p_head == NULL)//判断首节点是否为节点
{
printf("this is the link is NULL\n");
}
else//如果不是空节点
{
//如果是删除name则用(strcmp(pd->name,name) != 0)来进行判断
while(pd->num != num && pd->next != NULL )//判断从第一个节点开始的数和要查找的数是否相等,并且不是最后一个节点
{
pf = pd;//保存一下pd的位置
pd = pd->next; //不断的将下一个节点数据传递给pd,循环遍历一遍,没有做删除
}
if(pd->num == num)//如果找到相同的数据
{
if(pd == *p_head)//如果是首节点
{
*p_head = pd->next;//则将首节点的数据用下一个节点地址中的数据覆盖
free(pd);//因为记录pd记录了首节点
}
else//如果不是首节点
{
pf->next = pd->next;//将位置指向下一个节点,将下下一个数据传递给上一个节点
free(pd);
}
}
else//没有找到要删除的节点
{
printf("don't found the num\n");
}
}
}
void link_free(STU **p_head)//链表的释放
{
STU *pd,*pf;
pd = pf = *p_head;
while(pf != NULL) //记录首地址是否为空
{
pd = pf->next; //pd记录下一个节点地址
free(pf);//释放pf
pf = pd;
}
*p_head =NULL;//将首地址置为空
}
void link_inset_num(STU **p_head,STU *p_new)
{
STU *pb, *pf;
pb = *p_head;
if(*p_head == NULL)//链表为空
{
*p_head = p_new; //将新的数据传入首节点
p_new->next = NULL; //将新的数据缓存清空
}
else
{
while(pb->num <= p_new->num && pb->next != NULL)//循环查找链表中的num是否有比新的数据大
{
pf = pb;
pb = pb->next;
}
if(pb->num > p_new->num)//之前的while不断的循环将值传到pb中
{
if(pb == *p_head)//如果pb的值在首节点
{
p_new->next = pb;//将pb后面的数据传到新数据的下面
*p_head = p_new;//然后将新数据放到首节点
}
else//如果不是首节点,那就是中间插入
{
pf->next = p_new; //插在pf和pb中间
p_new->next = pb;//将pb后面的数据传到
}
}
else
{
pb->next = p_new;//如果都没有找到,则就是尾节点,在尾节点最后面插入新数据
p_new->next = NULL;//将数据后置为NULL
}
}
}
int main()
{
STU *head = NULL, *p_new = NULL,*pd = NULL;//对head首个节点地址初始化为0,p_new记录新节点地址
int num,i;
printf("please input the link number\n");
scanf("%d",&num);
for(i = 0;i < num;i++)
{
p_new = ( STU *)malloc(sizeof(STU));//每次循环,malloc申请一个新的节点
printf("please input you num , score, name\n");//给新节点赋值
scanf("%d %d %s",&p_new->num,&p_new->score,&p_new->name);
link_create_head(&head,p_new); //将新节点加入链表,将head的地址传给函数,地址对值进行操作
}
while (1)
{
printf("please input you search number:\n");
scanf("%d",&num);
if(num == 0)
{
break;
}
pd = link_search_num(head,num);
if(pd != NULL)
{
printf("find the number %d %d %s\n",pd->num,pd->score,pd->name);//找到节点的
}
else
{
printf("not find the same number\n");
}
}
link_print(head);
while (1)
{
printf("please iuput you delete num\n");
scanf("%d",&num);
if(num == 0)
{
break;
}
link_delete(&head,num);//传入你要删除的链表首节点的地址,还有数字
link_print(head);
}
while (1)
{
p_new = ( STU *)malloc(sizeof(STU));//每次循环,malloc申请一个新的节点
printf("please input new num , score, name\n");//给新节点赋值
scanf("%d %d %s",&p_new->num,&p_new->score,&p_new->name);
link_inset_num(&head,p_new);
link_print(head);
}
}
功能实现单链表的插入
链表的排序,从小到大
#include<stdio.h>
#include<stdlib.h>
//链表创建
typedef struct student
{ //数据域
int num;
int score;
char name[20];
struct student *next; //指针域
}STU;
//实现链表的num的查找
STU *link_search_num(STU *head,int num)//寻找节点中是否与num相同的值
{
STU *p_mov = head;
while(p_mov != NULL) //判断链表是否为空
{
if(p_mov->num == num) //寻找节点中的值是否和num相同
{
return p_mov;//如果找到了就返回他的地址
}
p_mov = p_mov->next;
}
return NULL;
}
//实现单链表的遍历,打印
void link_print(STU *head)//遍历链表,打印链表中的数据
{
STU *p_mov = head;
while(p_mov != NULL)
{
printf("%d %d %s\n ",p_mov->num,p_mov->score,p_mov->name);//打印数据
p_mov = p_mov->next;
}
}
//实现单链表的创建
void link_create_head(STU **p_head,STU *p_new) //创建链表,将传入的值放到数据的后面
{
STU *p_mov = *p_head; //把链表的第一个值传给p_mov
if(*p_head == NULL)// 如果链表为空,当第一次加入链表
{
*p_head = p_new;
p_new->next =NULL; //新来节点的下一节点置为空
}
else //第二次加入链表
{
while (p_mov->next != NULL)
{
p_mov =p_mov->next; //如果不为空,不断判断,找到最后一个值
}
p_mov->next = p_new; //找到后将值传入下一个节点
p_new ->next = NULL;
}
}
//实现链表中的删除
void link_delete(STU **p_head, int num)
{
STU *pd,*pf;
pd =*p_head;
if(*p_head == NULL)//判断首节点是否为节点
{
printf("this is the link is NULL\n");
}
else//如果不是空节点
{
//如果是删除name则用(strcmp(pd->name,name) != 0)来进行判断
while(pd->num != num && pd->next != NULL )//判断从第一个节点开始的数和要查找的数是否相等,并且不是最后一个节点
{
pf = pd;//保存一下pd的位置
pd = pd->next; //不断的将下一个节点数据传递给pd,循环遍历一遍,没有做删除
}
if(pd->num == num)//如果找到相同的数据
{
if(pd == *p_head)//如果是首节点
{
*p_head = pd->next;//则将首节点的数据用下一个节点地址中的数据覆盖
free(pd);//因为记录pd记录了首节点
}
else//如果不是首节点
{
pf->next = pd->next;//将位置指向下一个节点,将下下一个数据传递给上一个节点
free(pd);
}
}
else//没有找到要删除的节点
{
printf("don't found the num\n");
}
}
}
void link_free(STU **p_head)//链表的释放
{
STU *pd,*pf;
pd = pf = *p_head;
while(pf != NULL) //记录首地址是否为空
{
pd = pf->next; //pd记录下一个节点地址
free(pf);//释放pf
pf = pd;
}
*p_head =NULL;//将首地址置为空
}
void link_inset_num(STU **p_head,STU *p_new)
{
STU *pb, *pf;
pb = *p_head;
if(*p_head == NULL)//链表为空
{
*p_head = p_new; //将新的数据传入首节点
p_new->next = NULL; //将新的数据缓存清空
}
else
{
while(pb->num <= p_new->num && pb->next != NULL)//循环查找链表中的num是否有比新的数据大
{
pf = pb;
pb = pb->next;
}
if(pb->num > p_new->num)//之前的while不断的循环将值传到pb中
{
if(pb == *p_head)//如果pb的值在首节点
{
p_new->next = pb;//将pb后面的数据传到新数据的下面
*p_head = p_new;//然后将新数据放到首节点
}
else//如果不是首节点,那就是中间插入
{
pf->next = p_new; //插在pf和pb中间
p_new->next = pb;//将pb后面的数据传到
}
}
else
{
pb->next = p_new;//如果都没有找到,则就是尾节点,在尾节点最后面插入新数据
p_new->next = NULL;//将数据后置为NULL
}
}
}
void link_order(STU *head)
{
STU *pf,*pb,temp;
pf = head;
if(head == NULL)//判断链表是否为空链表
{
printf("the link is NULL");
}
while(pf->next != NULL)//如果链表不为空链表 pf指向的是基准节点
{
pb = pf->next; // pb从基准的下一个节点开始
while(pb != NULL)
{
if(pf->num > pb->num)//链表不为空以后pf 首节点的数和下一个节点pb的数进行比较
{
//进行交换数值和指针域
temp = *pf;
*pf = *pb;
*pb = temp;
temp.next = pf->next;//temp 的指针域和pf指向的指针域进行交换
pf->next = pb->next;
pb->next = temp.next;
}
pb = pb->next;
}
pf = pf->next;
}
link_print(head);
}
int main()
{
STU *head = NULL, *p_new = NULL,*pd = NULL;//对head首个节点地址初始化为0,p_new记录新节点地址
int num,i;
printf("please input the link number\n");
scanf("%d",&num);
for(i = 0;i < num;i++)
{
p_new = ( STU *)malloc(sizeof(STU));//每次循环,malloc申请一个新的节点
printf("please input you num , score, name\n");//给新节点赋值
scanf("%d %d %s",&p_new->num,&p_new->score,&p_new->name);
link_create_head(&head,p_new); //将新节点加入链表,将head的地址传给函数,地址对值进行操作
}
while (1)
{
printf("please input you search number:\n");
scanf("%d",&num);
if(num == 0)
{
break;
}
pd = link_search_num(head,num);
if(pd != NULL)
{
printf("find the number %d %d %s\n",pd->num,pd->score,pd->name);//找到节点的
}
else
{
printf("not find the same number\n");
}
}
link_print(head);
while (1)
{
printf("please iuput you delete num\n");
scanf("%d",&num);
if(num == 0)
{
break;
}
link_delete(&head,num);//传入你要删除的链表首节点的地址,还有数字
link_print(head);
}
while (1)
{
p_new = ( STU *)malloc(sizeof(STU));//每次循环,malloc申请一个新的节点
printf("please input new num , score, name\n");//给新节点赋值
scanf("%d %d %s",&p_new->num,&p_new->score,&p_new->name);
link_inset_num(&head,p_new);
link_print(head);
}
link_order(head);
}
链表的逆序遍历
#include<stdio.h>
#include<stdlib.h>
//链表创建
typedef struct student
{ //数据域
int num;
int score;
char name[20];
struct student *next; //指针域
}STU;
//实现链表的num的查找
STU *link_search_num(STU *head,int num)//寻找节点中是否与num相同的值
{
while (1)
{
printf("please input you search number:\n");
scanf("%d",&num);
if(num == 0)
{
break;
}
//pd = link_search_num(head,num);
if(head != NULL)
{
printf("find the number %d %d %s\n",head->num,head->score,head->name);//找到节点的
}
else
{
printf("not find the same number\n");
}
}
STU *p_mov = head;
while(p_mov != NULL) //判断链表是否为空
{
if(p_mov->num == num) //寻找节点中的值是否和num相同
{
return p_mov;//如果找到了就返回他的地址
}
p_mov = p_mov->next;
}
return NULL;
}
//实现单链表的遍历,打印
void link_print(STU *head)//遍历链表,打印链表中的数据
{
STU *p_mov = head;
while(p_mov != NULL)
{
printf("%d %d %s\n ",p_mov->num,p_mov->score,p_mov->name);//打印数据
p_mov = p_mov->next;
}
}
//实现单链表的创建
void link_create_head(STU **p_head,STU *p_new) //创建链表,将传入的值放到数据的后面
{
STU *p_mov = *p_head; //把链表的第一个值传给p_mov
if(*p_head == NULL)// 如果链表为空,当第一次加入链表
{
*p_head = p_new;
p_new->next =NULL; //新来节点的下一节点置为空
}
else //第二次加入链表
{
while (p_mov->next != NULL)
{
p_mov =p_mov->next; //如果不为空,不断判断,找到最后一个值
}
p_mov->next = p_new; //找到后将值传入下一个节点
p_new ->next = NULL;
}
}
//实现链表中的删除
void link_delete(STU **p_head, int num)
{
STU *pd,*pf;
pd =*p_head;
if(*p_head == NULL)//判断首节点是否为节点
{
printf("this is the link is NULL\n");
}
else//如果不是空节点
{
//如果是删除name则用(strcmp(pd->name,name) != 0)来进行判断
while(pd->num != num && pd->next != NULL )//判断从第一个节点开始的数和要查找的数是否相等,并且不是最后一个节点
{
pf = pd;//保存一下pd的位置
pd = pd->next; //不断的将下一个节点数据传递给pd,循环遍历一遍,没有做删除
}
if(pd->num == num)//如果找到相同的数据
{
if(pd == *p_head)//如果是首节点
{
*p_head = pd->next;//则将首节点的数据用下一个节点地址中的数据覆盖
free(pd);//因为记录pd记录了首节点
}
else//如果不是首节点
{
pf->next = pd->next;//将位置指向下一个节点,将下下一个数据传递给上一个节点
free(pd);
}
}
else//没有找到要删除的节点
{
printf("don't found the num\n");
}
}
}
void link_free(STU **p_head)//链表的释放
{
STU *pd,*pf;
pd = pf = *p_head;
while(pf != NULL) //记录首地址是否为空
{
pd = pf->next; //pd记录下一个节点地址
free(pf);//释放pf
pf = pd;
}
*p_head =NULL;//将首地址置为空
}
void link_inset_num(STU **p_head,STU *p_new)
{
STU *pb, *pf;
pb = *p_head;
if(*p_head == NULL)//链表为空
{
*p_head = p_new; //将新的数据传入首节点
p_new->next = NULL; //将新的数据缓存清空
}
else
{
while(pb->num <= p_new->num && pb->next != NULL)//循环查找链表中的num是否有比新的数据大
{
pf = pb;
pb = pb->next;
}
if(pb->num > p_new->num)//之前的while不断的循环将值传到pb中
{
if(pb == *p_head)//如果pb的值在首节点
{
p_new->next = pb;//将pb后面的数据传到新数据的下面
*p_head = p_new;//然后将新数据放到首节点
}
else//如果不是首节点,那就是中间插入
{
pf->next = p_new; //插在pf和pb中间
p_new->next = pb;//将pb后面的数据传到
}
}
else
{
pb->next = p_new;//如果都没有找到,则就是尾节点,在尾节点最后面插入新数据
p_new->next = NULL;//将数据后置为NULL
}
}
}
void link_order(STU *head)
{
STU *pf,*pb,temp;
pf = head;
if(head == NULL)//判断链表是否为空链表
{
printf("the link is NULL");
}
while(pf->next != NULL)//如果链表不为空链表 pf指向的是基准节点
{
pb = pf->next; // pb从基准的下一个节点开始
while(pb != NULL)
{
if(pf->num > pb->num)//链表不为空以后pf 首节点的数和下一个节点pb的数进行比较
{
//进行交换数值和指针域
temp = *pf;
*pf = *pb;
*pb = temp;
temp.next = pf->next;//temp 的指针域和pf指向的指针域进行交换
pf->next = pb->next;
pb->next = temp.next;
}
pb = pb->next;
}
pf = pf->next;
}
link_print(head);
}
STU *link_reverse(STU *head)//链表逆序遍历
{
STU *pf,*pd,*r;//*r保存下一个节点地址
pf = head;
if(head = NULL)//链表为空
{
printf("the link is NULL\n");
return ;
}
if(head->next = NULL)
{
printf("only one num\n");
return head;
}
pd = pf->next;
while (pd != NULL)
{
r = pd->next;//r保存一下他的后一个节点的地址
pd->next = pf;
pf = pd;
pd = r;
}
head->next = NULL;
return pf;//返回pf就是头节点
}
int main()
{
STU *head = NULL, *p_new = NULL,*pd = NULL;//对head首个节点地址初始化为0,p_new记录新节点地址
int num,i;
printf("please input the link number\n");
scanf("%d",&num);
for(i = 0;i < num;i++)
{
p_new = ( STU *)malloc(sizeof(STU));//每次循环,malloc申请一个新的节点
printf("please input you num , score, name\n");//给新节点赋值
scanf("%d %d %s",&p_new->num,&p_new->score,&p_new->name);
link_create_head(&head,p_new); //将新节点加入链表,将head的地址传给函数,地址对值进行操作
}
// while (1)
// {
// printf("please input you search number:\n");
// scanf("%d",&num);
// if(num == 0)
// {
// break;
// }
// pd = link_search_num(head,num);
// if(pd != NULL)
// {
// printf("find the number %d %d %s\n",pd->num,pd->score,pd->name);//找到节点的
// }
// else
// {
// printf("not find the same number\n");
// }
// }
head = link_reverse(&head);
link_print(head);
}