#此文章用于大一C语言的链表复习
这里就不再上链表官方定义了,直接说我对链表的理解。链表相当于内存中一系列不连续的地址通过指针相互联系在一起,它需要通过结构体来实现,同时引入了节点的概念,即以前我们通过一个变量来储存数据,现在在链表中用节点来储存数据,因为在链表中,一个数据总伴随着一个指向下一个数据地址的指针,所以这种形式的变量需要用结构体来实现,一个结构体变量里有存储数据的子变量,还有存储下一个结构数据的指针变量,这种形式很像火车车厢,有装载货物的地方,还有连接下一个车厢的钩子,一个节点中的指针变量就相当于那个钩子。
我画了一个图,我意识中的链表就是这样的,老师也这样画过。
之后是链表的基本操作
一.创建一个链表
1.头插法创建一个有头链表
#include <stdio.h>
#include <stdlib.h>//需要用到malloc函数
struct link
{
int data;//用于存储数据的地方
struct link *next;//用于指向下一个节点的指针
};//先创建结构体
int main(void)
{
struct link *head,*s;
head=(struct link*)malloc(sizeof(struct link));//首先要让指针head指向一块可供存储的空间,否则无法对其操作
head->next=NULL;//由于head只是一个单独的存在,所以下一个指向空
while(1)
{
s=(struct link*)malloc(sizeof(struct link));//让s指向一块可供存储的空间
scanf("%d",&s->data);//对s赋值
if(s->data==-1)//终止链表输入的条件
break;
s->next=NULL;//s的下一个指向空
s->next=head->next;//要断开head与它的下一个,把s插进去,所以必须先保存head的下一个的地址,即把head的下一个的地址给s的next指针
head->next=s;//连接head与s,反复此过程可进行连续的链表插入
}
head=head->next;//这里附上一个指针输出,以供直观测试
while(head!=NULL)
{
printf("%d ",head->data);
head=head->next;
}
return 0;
}
附录1:这里是一个能进行连续头插的方法,只需重复这两步就能实现连续的头插,但如果要生成一个正规可用的链表,则要求初始的单节点的next指针必须指向空。
附录2:在操作一个指针时,如果想给指针直接赋值,指针必须要指向一块有存储空间的地址,否则无法操作。指针最好先指向空,否则初始指针的指向是随意的,乱用可能会造成系统崩溃等一些严重的问题。
附录3:头插法按顺序输出是与输入是的顺序反向的,所以在做链表逆序的题时会用到头插法。
2.尾插法创建一个有头链表。
#include <stdio.h>
#include <stdlib.h>//需要用到malloc函数
struct link
{
int data;//用于存储数据的地方
struct link *next;//用于指向下一个节点的指针
};//先创建结构体
int main(void)
{
struct link *head,*tail,*s;//这里需要再声明一个tail进行尾插
head=(struct link*)malloc(sizeof(struct link));//首先要让指针head指向一块可供存储的空间,否则无法对其操作
head->next=NULL;//由于head只是一个单独的存在,所以下一个指向空
tail=head;//一开始tail与head指向重合
while(1)
{
s=(struct link*)malloc(sizeof(struct link));//让s指向一块可供存储的空间
scanf("%d",&s->data);//对s赋值
if(s->data==-1)//终止链表输入的条件
break;
s->next=NULL;//s的下一个指向空
tail->next=s;//tail的next指针指向s,二者连接起来
tail=s;//s成为下一个tail,下一个循环中又会有一个新的s插到后面,如此循环,最终创建好一个链表
}
head=head->next;//这里附上一个指针输出,以供直观测试
while(head!=NULL)
{
printf("%d ",head->data);
head=head->next;
}
return 0;
}
附录:尾插法的顺序是正常的,所以这也是一种非常常用的链表创建方法
关于有头节点的一个总结:由于创建时第一个节点的一些特殊性,导致有时第一个节点有值时会出现一些麻烦的情况,所以这时有一个数据为空的头节点有一些优势,同时有头节点在创建时思路较为简单,可操作性也很强,但有时会比无头节点多一步,会麻烦一些。
这里先写有头节点,因为我发现我对无头节点链表的理解并不是很透彻,同时我自己仿照书上的方法写了一个无头链表,发现我的编译器对其有报错,我打算换个编译器再试试,所以为了避免打扰其他人的思维,我先到此为止。