单链表 头插法

文章介绍了如何在C语言中使用结构体创建链表,特别是头插法插入元素的过程。通过定义包含指针的结构体实现链表节点,并提供了输入、添加、打印和释放链表内存的函数。文章强调了在结构体中递归调用自身时需要使用指针避免无限递归,以及在管理动态内存时的注意事项。
摘要由CSDN通过智能技术生成

链表基本形式:head ->信息域 —>信息域->NULL

结构体是不可以递归调用的,故下面代码错误

# include<stdio.h>

int main()
{
    struct Test
    {
        int x;
        int y;
        struct Test test;// 调用其他结构体可以,调用自己不可以,无限递归,除非加个指针 
    }; //链表就是自己指自己  单链表 双链表 循环链表
    //head ->信息域 —>信息域->NULL  链表PK数组 
    
    return 0;
 } 

加个指针

# include<stdio.h>

int main()
{
    struct Test
    {
        int x;
        int y;
        struct Test *test;// 调用其他结构体可以,调用自己不可以,无限递归,除非加个指针 
    }; //链表就是自己指自己  单链表 双链表 循环链表
    //head ->信息域 —>信息域->NULL  链表PK数组 
    
    return 0;
 } 

万能指针可以解决问题,而这种自己结构体调用自己结构体的方法就构成链表

链表就是自己指自己 单链表 双链表 循环链表,下面单链表 头插法的例子

信息域是指针信息域的后继是指针,那head就是指向信息域这个指针的指针

# include<stdio.h>
# include<stdlib.h>

//头插法 
 
     struct Book//结构体类型
    {
         char title[128];
         char author[40];//信息域 
         struct Book *next;//next是个指针
     } ;
     
     void getInput(struct Book *book)//传一个Book结构的指针 ,根据指针修改结构体的内容 
     {
          printf("请输入书名:");
          scanf("%s",book->title) ;//传过来的是指针,直接用 箭头 
          printf("请输入作者:");
          scanf("%s",book->author) ; 
     }
     

     void addBook(struct Book **library)//因为要修改*library的值,所以要修改*library的地址 
     {
           struct Book *book,*temp;//定义Book结构体指针变量book,中间指针变量temp
           
             book= (struct Book *)malloc(sizeof (struct Book)) ;//强制类型转换为stuct Book类型的指针变量
             if(book==NULL)
             {
             printf("内存分配失败了!\n");//通常是不会分配失败,一切为了代码的健壮性 
             exit(1);//强制退出,给他一个错误代码1 
             //这需要<stdlib.h>头文件支持 
         
             }
             
             getInput(book); //用户填充信息域 用getInput函数实现 ,传过去的参数就是结构的地址 book 
             
             if(*library!=NULL)//不等于NULL说明中是有数据的 
             {
                 temp=*library;//先将都信息域指针赋给一个临时变量 
                 *library=book;//将信息域指针转向新开的book 
                 book->next=temp;//最后将book->next只想原来的信息域,此时temp就是存放原来信息域的地址     
             }
             else//等于NULL比较容易 
             {
                 *library=book;//将头指针指向新生成的节点 book就是新生成信息域的地址 
                 book->next=NULL;//再将新的后继指向NULL 
             }
         
      } 
      
void printLibrary(struct Book *library)//打印书的内容  传递的是信息域的指针 
{
    struct Book *book;//因为我们要打印一本本书,所以将liberay传给book,提高可读性 
    int count=1;//count用来计算打印了多少本 
    
    book= library;
    while(book!=NULL)
    {
        printf("Book%d:\n",count );
        printf("书名:%s\n",book->title);
        printf("作者:%s\n",book->author);
        book=book->next;
        count++;
    }
}

void releaseLibrary(struct Book *library)//malloc申请的内存空间要用free给他释放掉 
{
    while(library!=NULL)
    {
        free(library);
        library=library->next;//有错误 
    }
 } 

int main(void)
{
        struct Book *library=NULL;//头指针是结构体的地址 现在是空的单链表 
        int ch;
        
        //addBook(&library);//library是 信息域的地址,我们要想修改信息域指针的地址 
        
        while(1)//死循环 
        {
            printf("请问是否需要录入书籍信息(Y/N):");
            do
            {
                ch=getchar();
            }while(ch!='Y'&&ch!='N');//为了程序的健壮性
            
            if(ch=='Y')
            {
                 addBook(&library);//传入的是的地址 
                
            }
            else
            {
                break;//退出死循环 
            }
        }
        printf("请问是否需要打印图书信息(Y/N):");
        do
        {
            ch=getchar();
            
         } while(ch!='Y'&&ch!='N');
         
         if(ch=='Y')
         {
             printLibrary(library);
    
         }
         
                  releaseLibrary(library);
     
    return 0;
 }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值