链表基本形式: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;
}
万能指针可以解决问题,而这种自己结构体调用自己结构体的方法就构成链表
链表就是自己指自己 单链表 双链表 循环链表,下面单链表 头插法的例子
![](https://i-blog.csdnimg.cn/blog_migrate/cc6f7170240cc187e640cf37786e6803.png)
信息域是指针信息域的后继是指针,那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;
}