数据结构之单向链表

链表
是一种物理存储上非连续,数据元素的逻辑顺序通过链表中的指针链接次序,实现的一种线性存储结构
特点:
链表由一系列节点(链表中每一个元素称为节点)组成,节点在运行时动态生成(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);


}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值