链表属于c语言中的一块硬骨头,因为链表的概念比较抽象,而且其中使用到了一级指针或者是二级指针,指针也是c语言中比较让人头疼的问题,所有链表的难度,不说自明,本文仅讲自己学习了一段时间的链表之后所产生的对于链表的看法,仅个人思路,如果有错误的地方,欢迎大家指出来,如果不想指出来,可以把本文当娱乐来当个笑话。
链表的概念
为了方便理解,先来画一个简单的图来帮助大家了解一下链表。
首先先说指针,指针是说,在存储的内存条里面,申请一块区域,将自己想要的信息的地址存入到内存格之中,在以后的使用中可以通过找到地址位置来进行间接的查找出所要的内容。类似于,你的将箱子的钥匙放到抽屉里面,你要想要打开箱子,就需要先找到存放钥匙的抽屉的位置,然后再拿钥匙来打开箱子。
链表的优势:我们在进行编程时,其实更多的时候,并不知道自己需要输入多少的数据,所有往往会开辟一个比较大的内存来存放数据,造成了很多的浪费,而链表则是通过动态分配来进行资源的合理分配,能够节省很多的内存空间。
而想要实现链表,链表,顾名思义,他需要链条来把本来并不串联的数据来连接起来,如图:
每一块单元,又叫做一个结点,通过指针来串联到一起,我们需要先定义一个结点的类型:
struct stud_node{
int num; //号码
struct stud_node *next; //指针 其中next顾名思义就是下一个的意思
};
定义的结点类型比较简单,我们要实现链表,就要先学会怎么进行输入。参考一道题目来进行了解
---------------------------------------------------------------------------------------------------------------------------------
本题要求实现一个将输入的学生成绩组织成单向链表的简单函数。
函数接口定义:
void input();
该函数利用scanf
从输入中获取学生的信息,并将其组织成单向链表。链表节点结构定义如下:
struct stud_node {
int num; /*学号*/
struct stud_node *next; /*指向下个结点的指针*/
};
单向链表的头尾指针保存在全局变量head
和tail
中。
输入为若干个学生的信息(学号),当输入学号为0时结束。
解释为什么要使用全局变量,其实这在链表里面属于违法的,但是却是当前来说最节省时间的做法,一共有四种方式可以让定义的函数返回原本程序,可以去翁恺C语言程序设计的课里面进行了解,在小破站就可以搜到。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
struct stud_node {
int num;
struct stud_node *next;
};
struct stud_node *head, *tail; //全局变量
void input();
int main()
{
struct stud_node *p;
head = tail = NULL;
input();
for ( p = head; p != NULL; p = p->next )
printf("%d %s %d\n", p->num;
return 0;
}
/* 你的代码将被嵌在这里 */
void input(){
struct stud_node *p; //定义一个指针
int x; //x为输入的学号
scanf("%d",&x);
while(x){ //当while为0是停止
p = (struct stud_node *)malloc(sizeof(struct stud_node)); //给结点一个内存空间
p->num = x; //将输入的学号赋给结构体里的num
p->next = NULL; //结构体里的next是一个指针,我们给他赋为NULL
if(head==NULL){ //在测试代码中,head是NULL,所有我们先要让head有意义
head = p;
}
else{ //如果已经存在一个head,代表链表不为空
tail->next = p; //将tail指向p,p作为新的tail
}
tail = p; //最后一个,也就是说,tail已经到了最后一个了,那么只需要把p给tail
scanf("%d",&x); //输入x,来判断是否进行下一个while循环
}
}
特别鸣谢,我的老师,我的同学们帮我解答迷津 。