写在前面:
- 1.首先链表的本质只是一种特殊的结构体,所以C语言当作并没有现成的函数去帮助你延长链表或者帮助你输出链表,所有的东西全部需要靠你自己.
- 2.学习链表之前需要的预备知识:结构体,指针,动态内存分配.
P.S.链表本身并不需要动态内存分配,但是可以确保你在函数中生成的链表所占用的内存不会在函数结束后被释放.
PP.SS.如果你看不懂上面那句话,不明白我在说什么可以学习一下C语言中变量的生存周期和动态内存分配.
1.什么是链表
在之前已经说过链表不过是定义特殊的结构体
先来在逻辑上理解一下链表
这里借用一下另一个blog的图片:https://blog.csdn.net/morixinguan/article/details/68951912
链表这种结构体的特殊之处在于有一个*next.
*next为一个指向这种结构体的下一个节点的指针,这种结构体中均有一个*next
当你访问首位链表时*next中存放了链表中的下一个节点的地址如此将本互不相连的若干个结构体连接了起来,同时这些结构体数据类型又相同如此起到了一种类似于数组却比数组更加方便的数据类型,被称为链表.
这条链从Head开始(即链表第一个节点的地址)最后一个节点依然有*next不过它的值等于NULL.
2.如何定义一个链表
如下是一个链表的定义.
struct student {
int num,score;//这就是我们所说的数据域
struct student *next;
};//定义一个结构体(链表)
数据的多少名称大小都可以自己定义.
3.如何使用
定义好了链表接下来便是如何使用它
这里我便以例代讲:
#include<stdio.h>
#include<malloc.h>
/* User Code Begin(考生可在本行后添加代码,定义程序中使用的结构体类型、声明自定义函数的原型,行数不限) */
struct student {
int num,score;
struct student *next;
};//定义一个结构体(链表)
struct student *creat(void);
struct student *merge(struct student*a,struct student*b);
/* User Code End(考生添加代码结束) */
/* print以规定的格式完成遍历显示指定的链表 */
void print(char *Info, struct student *Head);
int main(void)
{
struct student *ah, *bh;
printf("创建链表A,请输入学号及成绩(均输入为0时表示停止):\n");
ah = creat();
printf("\n创建链表B,请输入学号及成绩(均输入为0时表示停止):\n");
bh = creat();
print("\n链表A:", ah);
print("\n链表B:", bh);
ah = merge(ah, bh);
print("\n链表A、B合并后:", ah);
return 0;
}
void print(char *Info, struct student *Head)
{
printf("%s", Info);
while (Head != NULL)
{
printf("%d,%d ", Head->num, Head->score);
Head = Head->next;
}
}
/* User Code Begin(考生在此后完成自定义函数的设计,行数不限) */
struct student *creat(void)//定义函数建立链表
{
struct student *Head,*p1,*p2;//*Head是这个链表的首地址单独定义并且保存下来
int n=1;
Head=p1=p2=(struct student*)malloc(sizeof(struct student));
while(1)
{
printf("学生 %d: ",n);
scanf("%d %d",&(p2->num),&(p2->score));
//通过p2保存输入的数据
if(p2->num==0 && p2->score==0)
//普判断是否要结束输入
{
if(n==1)
{
return NULL;//如果没有输入任何数据就直接要求结束输入就返回NULL
}
return Head;//否则返回链表首地址
}
if(Head==NULL)//判断是否是第一位链表
{
//如果是链表的第一位的话执行如下操作
Head=p2;//做为Head保存下来
p1=p2;//同时赋值给p1方便修改next
p2= (struct student *)malloc(sizeof(struct student));//为p2分配新地址
}
else
{
//如果不是第一位的话:
p1->next=p2;//为p1中next赋值为p2
p2->next=NULL;//将p2中next定义为null
p1=p2;//将p2的地址赋值给p1
p2= (struct student *)malloc(sizeof(struct student));
//为p2分配新的地址
}
n++;
}
}
struct student *merge(struct student *a,struct student *b)//定义函数合并两个链表
{
struct student *HEAD=a;
struct student *mid=NULL;
while(1)
{
if(a==NULL)
{
HEAD=b;
return HEAD;
}
if(a->next==NULL)
{
a->next=b;
return HEAD;
}
else
{
a=a->next;
}
}
}