**关于链表的认识**:
1.链表是一系列的存储数据元素的单元通过指针串接起来形成的。
这个存储单元包括两个域,一个域存放储存的内容,另一个域存放指
针,用于连接不同的存储单元。这就好比一条项链,这条“项链”具有
表头与表尾,是具有方向性的。
如图:
2.如何实现信息的存储?这里我们需要使用三个指针来充当记录的
工具。第一个指针指向头结点,目的是记住这条单链表的位置,便
于通过这个指针查找到它(*我们暂且可把它看做饭店的老板娘,
想联系饭店就找她*);第二个指针用于指向要即将加入这条单链表
的储存单元(*类似于站在门外的服务员吧*),第三个指针则是将
第二个指针带来的一个节点(客人),引到它正确的位置,并停留
在他的身旁,我们不难发现这个指正永远指向最后的那个节点(停
留在最近来的一位客人的身旁),三个指针的类型还必须和节点存
储域中的类型相同,才能顺利完成服务。当然每一个节点(客人)
也具有一个指针,用于指向新来的节点的地址,这样就可以形成
一个单链表了。
3.当我们将信息以单链表的形式储存后,又将面临如何输出的问
题.当然单链表的有序性,让这一功能很容易实现。我们只需要
找到头结点,然后利用每一个节点的指针将信息依次输出即可。
工作的流程可看图理解:
下面我将以一个具体的代码案例展示链表的功能(该代码的功能是将学生的部分信息储存到链表中并输出):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define N 10
/*定义结构体*/
struct Student
{
int id;//学号
char name[10];//姓名
int math;//数学成绩
struct Student *next;//定义结构体指针
};//定义一个结构体,该结构体用于存储学生的信息
typedef struct Student STUDENT;//运用typedef函数将结构体重命名为STUDENT
/*将信息存入链表*/
int main()
{
int t_id,t_math;
char t_name[10];
STUDENT *head,*p,*q;//head头指针,p当前指针,q前一个指针;建立第一个头结点的时候,head,p,q指向同一个结点(工具指针)
int flagHead=0;//通过标记flagHead实现指针的初始化,所有指针指向头结点,但是只实现一次
while(1)//通过循环,可以一直存入新的节点,不用担心空间的容量
{
scanf("%d%s%d",&t_id,t_name,&t_math);//输入一个学生的相关信息
if(t_id < 0)
{
break;//这里我们将循环结束的条件定义为,输入一个学号为负数的数,则跳出循环
}
p=malloc(sizeof(STUDENT));//为指针分配空间,可理解为p成为了这块空间的代理人
if(flagHead == 0)
{
head=p;//只做一次,建立第一节点(结点)
q=p;
flagHead=1;
}//完成这一步,将三个指针都指向一个节点空间
p->id=t_id;
strcpy(p->name,t_name);//必须使用strcpy函数存入t_name,否则报错
p->math=t_math;
p->next=NULL;
//这一步完成后,节点将存入学生信息,并且该节点是由p管理
q->next=p;//p将管理的节点交给q的next,于是这个新的节点完成了与上一个节点的连接,于是它变成了最后一个节点
q=p;//因为q只管理最后一个节点,所以p将自己的管理的新节点地址交给q,再回到上面p将获得新的空间,存入新的信息,组装新的节点
}
/*将信息从链表中输出*/
p=head;//将head指针交给p,即将这条单链表的地址交给了p
while(p != NULL)//单链表的最后一个节点的指针域是空的,以此判断单链表是否到达链尾,到达链尾,则跳出循环
{
printf("%d,%s,%d\n",p->id,p->name,p->math);//将单链表的节点信息输出
p=p->next;//完成一个节点信息输出后,将下一个节点交给p,p指向下一个节点。
}//通过循环,就将单链表遍历一次后,将储存的信息全部输出
return 0;
}
为了使大家更好理解,注释较多,本人新手一只,恐难以表述正确,
如果发现有任何问题,欢迎各位大佬指正。
最后送上一句共勉的话:人生短暂,尽情发光发热吧!