1、链表
1.1 为什么学习链表
学完C语言之后我们至少可以通过两种结构来存储数据,一种是“数组”,另一种是“链表”。
1.1.1 数组的缺点
1)当存储数据过多时,需要内存空间较大。
2)数组的存取速度很快,但是数组插入和删除元素的效率很低。
3)用数组存放数据时,必须事先定义固定的长度,如果事先难以确定数组的长度,就必须将数组定义得足够大,这样显然会浪费很多内存。
1.2 链表
1)由于链表中每一个元素都多包含了一个地址,或者说是多包含了一个存放着地址的指针变量,所以相对而言会占用比较多的内存,空间的开销会比较大。
2)由于链表中各个元素在内存中不是连续存放的,所以要找到其中的某一个元素,必须先找到该元素的上一个元素,然后根据上一个元素提供的下一个元素的地址才能找到该元素。所以如果不提供“头指针”,那么整个链表都无法访问。
3)数据的存储分为两大类:顺序存储和链式存储。按逻辑又可分为线性结构和非线性结构。线性结构主要有线性表(数组和链表),而非线性结构主要有树和图。
4)数组和链表都可以实现栈和队列,但是说实在话,栈和队列要是用数组实现的话就意义不大(数组的缺点),因此用链表。因为栈和队列的主要操作就是插入和删除,所以用链表实现比较合适。
5)链表是理论,栈和队列是应用,且栈和队列要比链表简单得多。
1.3 定义
链表分为单向链表、双向链表、单向循环链表、双向循环链表。如下所示为单向链表。
链表中每一个元素称为“结点”,每个结点都包括两部分,一部分是“用户需要的实际数据”,另一部分是“下一个结点的地址”。
链表有一个“头指针”变量,它存放一个地址,该地址指向“头结点”,头结点中不存放数据,只存放第一个元素的地址。
链表从第一个元素开始存放数据,第一个元素称为**“首结点”,首结点中又存放第二个元素的地址**。
尾结点的地址部分存放一个**“NULL”,表示“空地址”,链表到此结束。NULL在链表程序中往往作为链表结束**的判断标志。
确定一个链表只需要一个参数——头指针。
1.3.1 定义形式
用结构体表示链表:
struct student
{
long num;
float score;
struct student *next;
};
其中成员num和score用来存放结点中的有用数据,next是指针类型的成员,它指向struct student类型数据。
一个指针类型的成员既可以指向其他类型的结构体数据,也可以指向自己所在结构体类型的数据。用这种方法就可以建立链表
(未完待续。。。。。。)