链表的基本概念
链表
能实现线性结构,但在空间上可以是不连续的,与数组不同,但其在数据储存上是连续的
1.链表的命名,和其节点的命名
2.头指针,指向链表的指针
3.首元节点,储存第一个数据的节点
4.头节点,不储存数据,被头指针指向,自身指向首元节点
链表的命名和头指针的命名
typedef struct _NODE_ {
int number;
struct _NODE* next;
}Node,*Lintlist;
在这里node与list所代表的数据类型是不一样的
Node是通过typedef把这个结构体这个数据类型命名为Node
Linklist是指向一个指针,而这个指针指向的数据类型是结构体,然后通过typedef来给这个指针命名为Linklist
在这里要用两个数据类型来表示是有原因的
增加可读性
node节点
我们在创造节点时通常用malloc函数声明
Node* p = (Node*)malloc(sizeof(Node))
在这个时候如果我们要声明一个指针指向这个链表,那就出现一个问题那就是,如果还用node*来声明,我们会难以判断这个声明的到底是节点还是这个链表
还有一个问题,我们在学习时老师总是用head来充当这个头指针,那在这种情况下如何给这个链表命名,我们不能说用head来命名
一个链表还好,而且在我们学习时也可以,但是当我们工作后,你这个代码别人能读明白,答案是不能
而这个时间我们就需要一个新的数据类型来单独给这个链表命名,Linklist就是这个数据类型,指向结构体的指针
在我们用Link list来命名时其他人就会知道这个命名的是一个链表,而不是一个节点
首元节点和头节点
首元节点,链表第一个储存数据的节点
在没有头节点的链表中,头指针指向首元节点
但这也就会导致一个问题,在我们对头结点进行操作时,增删,会导致头节点的改变,然后我们就需要让头指针指向也发生改变
即我们在进行增减操作时,需要先判断是否为首元节点,然后在进行操作,首元节点和其他节点的操作是不一样的
这会让我们的编程更加复杂,可读性也不高
所以我们引入了头节点
在有头节点的链表中,我们会使头指针指向头节点,然后头节点再指向首元节点,这样会使我们对首元节点的操作和其他节点的操作一样,
也统一了空表和非空表的表示,
在没有头节点的链表中
空表是根据头指针是否指向空来确定的
再有头节点的链表中
空表是根据头节点的指向是否为空表示的
而头节点的命名和其他节点的命名是一样的
与头指针的命名是不同的,所以可以统一空表和非空表的判定,不需要通过头指针来确认。

浙公网安备 33010602011771号