* 9.4 用指针处理链表
9.4.1 什么是链表
链表是一个常见的重要数据结构。它是动态地进行存储分配的一种结构,它根据需要开辟内存单元。
链表有一个"头指针"变量,图中以head表示,它存放一个地址,该地址指向一个元素。链表种每一个元素称为"结点",每一个结点都应包括两个部分:
- 用户需要用的实际数据
- 下一个结点的地址。
可以看出,head指向第一个元素,第一个元素又指向第二元.......直到最后一个元素,该元素不再指向其他元素,它称为"表尾",它的地址部分放一个”NULL“(表示“空地址”),链表到此结束。
可以看到链表各个元素在内存中的地址可以是不连续的。这就是说明要找一个元素,得先到上一个元素,根据它提供的下一个元素地址才能找到下一个元素。如果不提供“头指针”,则整个链表就无法访问。
显然,链表这种数据结构,必须利用指针变量才能实现,即结点中应包含一个指针变量,用它存放下一个结点地址。
前面介绍了结构体变量,用它建立链表是最合适的。一个结构体变量包含若干个成员(成员可以是int,char,float等类型)。用指针类型成员来存放下一个元素的地址。
struct Student
{
int num;
float score;
struct Student *next;
};
程序分析:num和score存放结点中的实际数据,next是指针类型的成员,它指向struct Student 类型数据(就是next所在的结构体类型)。
注意:上面只是定义一个stuct Student类型,并未实际分配存储空间,只有定义了变量才分配存储空间。
9.4.2 建立简单的静态链表
例题:建立一个简单的链表,它右3个学生数据的结点组成,要求输出各个结点的数据。
#include<stdio.h>
int main(){
struct Student
{
int num;
float score;
struct Student *next;
};
struct Student a, b, c, *head, *p;
a.num = 193060101;
a.score = 88.88;
b.num = 193060102;
b.score = 87.4;
c.num = 193060103;
c.score = 85.12;
head = &a;
a.next = &b;
b.next = &c;
c.next = NULL;
p = head;
do{
printf("%d%10.2f\n", p->num, p->score);
p=p->next;
} while (p != NULL);
return 0;
}
运行结果:
程序分析:
为了建立链表,使head指向a结点,a.next指向b结点,b.next指向c结点,这就构成了链表关系。“c.next = NULL”的作用是使c.next不指向任何有用的存储单元。
在输出链表时要借助p,使p指向a结点,然后输出a结点中的数据,“p=p->next”是为了下一个结点所做的准备。
9.4.3 建立动态链表
9.4.4 输出链表
博主还没学会,之后更新。