持续分享嵌入式技术,操作系统,算法,c语言/python等,欢迎小友关注支持
链式存储的定义
采用链式存储结构的线性表称为链表 。
不要求逻辑上相邻的两个数据元素物理上也相邻,它是通过“链”建立起数据元素之间的逻辑关系。
因此对线性表的插入、删除不需要移动数据元素,只需要修改“链”
为了便于理解可以通过下图表示:
从上面可以看出,第一张图表示的是链表里面的数据,第二张图表示的是数据在存储空间里面具体存储的位置,数据明显是不连续的。既然数据是不连续的,那么我们要如何访问呢,下面我们来一一探讨。
链表的特点
上面遗留了一个问题,数据存储不连续,我们要怎么访问数据,这一点跟链表的结点数据有关。
每个结点都有两个部分组成
数据域:存储元素数值数据
指针域:用来存储数据元素的直接后继的地址(或位置)
链表其实就是n 个结点由指针链组成一个链表。它是线性表的链式存储映像,称为线性表的链式存储结构。通过每个结点的指针域来访问后续结点的数据
链表因为指针域的不同可以实现不同的功能,主要有以下几点:
- 结点只有一个指针域的链表,称为单链表或线性链表。
- 有两个指针域的链表,称为双链表。
- 首尾相接的链表称为循环链表。
单链表的存储结构及相关方法
由上图可知,链表有头指针和首元结点,它们的含义表示为:
头指针是指向链表中第一个结点的指针。
首元结点是指链表中存储第一个数据元素a1的结点。
其中head=NULL表示链表为空表,
链表的存储结构描述:
typedef int datatype;
typedef struct link_node {
datatype info;
struct link_node *next;
}node;
typedef node * linklist;
// linkList为node指针类型
其中info用来存储每个结点具体的数据,指针next指向后继结点的地址。
建立空链表
node *init() {
return NULL;
}
单链表的遍历
实现方法:
工作指针后移。从首元结点(或开始结点)出发,通过工作指针的反复后移而将整个单链表“审视”一遍的方法称为扫描(或遍历)。
代码实现
void display(linklist head)
{
linklist p;
p=head;
if(p==NULL)
printf("\n单链表是空的!");
else
{
printf("\n单链表各个结点的值为:\n");
while(p) {
printf("%5d",p->info);
p=p->next;
}
}
}
查找某个结点的数据
实现方法:
1:工作指针p初始化; 累加器count初始化;
2:重复执行下述操作,直到p为空或者count==i:
>工作指针p后移;
>count++;
3:返回p指针;
代码实现
linklist findKth(linklist head,int i) {
int j=1;
linklist p=head;
while(p!=NULL && j<i) {
p=p->next;
j++;
}
return p; /* 找到第i个,返回第i个结点指针 */
/* 如果没有找到,此时p==null,返回空 */
}
查找值为x的结点
实现方法
1:工作指针p初始化;
2:重复执行下述操作,直到p为空或者p->info==x:
>工作指针p后移;
3:返回p指针;
代码实现
linklist find(linklist head,datatype x)
{
linklist p=head;
while(p!=NULL && p->info!=x)
{
p=p->next;
}
return p; /* 如果找到x所在的结点,p!=null ,如果没有找到,此时
p=null; 所以直接返回p即可,不需要判断 */
}
上面就是单链表的一些基本操作和概念,下一节我们来聊聊链表的插入和删除是实现方法。
如果觉得文章对你有帮助,请点赞关注下。如有错误欢迎指正