- 何谓链表?
链式存储的线性表,简称链表。链表由多个链表元素组成,这些元素称为节点。结点之间通过逻辑连接,形成链式存储结构。
存储结点的内存单元,可以是连续的也可以是不连续的。逻辑连接与物理存储次序没有关系
- 建立简单的静态链表
例: 建立一个如图所示的简单链表,它由3个学生数据的结点组成,要求输出各结点中的数据。
#include
struct Student
{
int num;
float score;
struct Student *next;
};
int main()
{
struct Student a,b,c,*head,*p;
a. num=10101;
a.score=89.5;
b. num=10103;
b.score=90;
c. num=10107;
c.score=85;
head=&a;
a.next=&b;
b.next=&c;
c.next=NULL;
p=head;
do
{
printf(“%ld%5.1f\n”,p->num,p->score);
p=p->next;
}while(p!=NULL);
return 0;
}
- 建立动态链表
所谓建立动态链表是指在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,
并建立起前后相链的关系。
例: 写一函数建立一个学生数据的单向动态链表,以学号为0结束链表的创建。
解题思路:- 定义3个指针变量:head,p和p1,它们都是用来指向struct Student类型数据struct Student *head,*p1,*p2;
- 用malloc函数开辟结点,并使p指向它
- 用scanf函数输入学号和成绩存到p->num,p->score的内存空间
- 断p->num是否为0,为0释放开劈的空间并结束链表的创建,若不为0,head存放第1个结点,
使p1始终指向最后1个结点(新开劈的空间),下次开劈的空间将存放到 p1->next中。
#include // 包含标准输入输出头文件
#include // 包含标准库头文件
struct Student //定义Student结构类型
{
int num; //学号
float score; //成绩
struct Student *next; //指向下一个学生结构体类型Student
};
#define LEN sizeof(Student) //宏定义计算结构体大小
struct Student* create(void); //函数声明
int main(void) //主函数,程序的入口
{
struct Student *head; //定义Student结构体指针head,用来接收链表的头部
head = create(); //调用create函数创建链表
while(head != NULL) //链表是否为空,即指向0地址将结束while循环
{
printf("num=%d,score=%.1f\n",head->num,head->score); //打印学号和成绩
head = head->next; //移动到链表的下一个结点
}
//链表空间释放
return 0;
}
/*
创建一个链表,学号为0结束键表创建
*/
struct Student* create(void)
{
struct Student *head=NULL; //定义Student结构体指针head,并赋初值NULL,即指向0地址,head指
// 针用来存放链表的首地址
struct Student *p; //定义Student结构体指针p,用来存放新开劈的Student地址
struct Student *p1; //定义Student结构体指针p1, 用来存放最后一个Student地址
do
{
p = (struct Student*)malloc(LEN); //使用malloc函数动态申请一块Student大小的内存,
//并将内存首地址返回给p
printf("请输入学号和成绩\n"); //打印一行提示
scanf("%d,%f",&p->num,&p->score); //输入学号和成绩
p->next = NULL; //将next指向0地址
if(p->num ==0) //学号为0结束链表创建
{
free(p); //释放无效学号分配的空间
p = NULL; // p指向0地址,防止野指针出现
}
else
{
if(head == NULL)
{
head = p; //链表第一次创建,用head指针来指向键表的头部
//(链表的首地址)
}
else
{
p1->next = p; //将最后一个链表的next指向新开劈的Student首地址
}
p1 = p; // p1重新指向最后一个Student地址,也就是新开劈的
// Student地址
}
}while(p != NULL); //p指向0地址将结束do ...while循环
return head; //将链表的首地址返回
}