链表的实质,在我认为是线性表,线性表的实现分为两种,一种是顺序存储另外一种就是链式存储结构,本文中所讨论的线性表为链式存储结构(以下称链表)。
链表相比于顺序存储结构的优势在于不要求逻辑上相邻的元素在物理位置上也相邻,在获得这个优点的同时,链表也失去了顺序存储结构的优点---随机存储。
简单的来说,链表由一系列不必在内存中连续的结构组成。每一个结构都含有表元素和指向包含该元素的后继元的结构的指针,我们称之为Netx指针,最后一个单元的Next指针指向NULL,即指向空;因此就有以下定义的结构体表示的链表节点:
/*定义线性链表的结构*/
typedef struct LNode
{
int date;//数据域struct LNode *next;//指向下一个节点的指针,即指针域}LNode;
链表又细分为带有头结点和不带头结点的链表,在这里主要讲述带有头结点的链表。
定义了链表的存储结构之后,万事开头难,有了节点的定义,这个时候我们就需要创建新的链表并且初始化(即给节点的数据域赋值),这里介绍常用的创建方法之一:尾插法
图中就是尾插法创建链表的算法原理(图源水印),具体代码实现:
LNode* CreateList(int n)
{
LNode* s;
LNode* r;//分别创建用来指向新节点(s)和尾节点(r)的指针
/*我认为这里是对节点L的重复初始化,但是在主函数中不对节点L进行初始化会报错 L未被初始化*/
LNode *L = (LNode*)malloc(sizeof(LNode));
L->next = NULL;
r = L;
for (int i = 0; i < n; i++)
{
s = (LNode*)malloc(sizeof(LNode));//为新节点申请内存空间
printf("输入数据:");
scanf("%d", &s->date);
r->next = s;//将新节点“连接”在尾节点之后
r = s;//新节点变为尾节点
}
if(L->next !&