数据结构-线性表的链式存储结构

术语:

1.结点:数据元素的存储映像。有数据域和指针域两部分组成。

2.链表:n个结点由指针组成一个链表

3.结点只有一个指针域的链表,成为单链表或线性链表。

4.结点有两个指针域的链表,成为双链表。

5.首尾相接的链表成为循环链表。


复制代码
//单链表的存储结构
typedef struct LNode
{
	ElemType data;//结点的数据域
	struct LNode *Next;//结点的指针域
}LNode,*LinkList;//LinkList为指向结构体Lnode的指针类型
复制代码
//单链表的初始化
Status InitList(LinkList &L){
	L=new LNode;//生成新节点作为头节点,头指针指向头节点
	//L=(LinkList) malloc (sizeof(LNode));
	L->next=NULL;//头节点的指针域置空
	return OK;
}

判断链表是否为空

复制代码
//单链表的销毁
//从头指针开始,依次释放所有结点
Status DestoryList(LinkList &L){
	Lnode *p;
	while(L){
		p=L;
		L=L->next;
		delete p;
	}
}

//清空单链表
//链表仍存在,但链表中无元素,成功空链表(头指针和头节点仍然存在)
Status ClearList(LinkList &L)
{
	Lnode *p,*q;
	p=L->next;
	while(p){//没到表尾
		q=p->next;
		delete p;
		p=q;
	}
	L->next=NULL;
	return OK;
}

//求单链表的表长
int ListLength_L(LinkList L){
	LinkList p;
	p=L->next;//p指向第一个结点
	i=0;
	while(p){//遍历单链表,统计结点数
		i++;
		p=p->next;
	}
	return i;
}

/**
单链表的取值:取单链表中第i个元素的内容
算法步骤:
1.用指针p指向首元节点,用j做计数器初值赋值为1
2.从首元结点开始依次顺着链域next向下访问,只要指向当前结点的指针p不为空,并且没有到达序号为i的结点,则循环执行以下操作
P指向下一个结点
计数器j相应加1
3.推出循环时,如果指针p为空,或者计数器j大于i,说明指定的序号i值不合法(i大于表长n或i小于等于0),取值失败,否则取值成功,此时j=i时,p所指的结点就是要找的第i个结点,用参数e保存当前结点的数据域,返回ok;
**/
Status GetElem(LinkList L,int i,ElemType &e)//获取线性表L中的某个数据元素的内容,通过变量e返回
{
	p=L->next;
	j=1;
	while(p&&j<i)//向后扫描,直到p指向第i个元素或p为空
	{
		p=p->next;
		++j;
	}
	if(!p||j>i){
		return error;
	}
	e=p->data;
	return OK;
}

/**
按值查找:根据指定数据获取该数据所在的位置(该数据的地址)
算法步骤:
1.用指针p指向首元节点
2.从首元结点开始依次顺着链域next向下访问,只要指向当前结点的指针p不为空,并且指向当前结点的指针p不为空,并且p所指结点的数据域不等于定值e,则循环执行以下操作
P指向下一个结点
3.若查找成功,p此时即为结点的地址值,若查找失败,p的值即为Null
**/
LNode *LocateElem(LinkList L,ElemType e)
{
	p=L->next;
	while(p&&p->data!=e)
	{
		p=p->next;
	}
	if(!p||j>i){
		return error;
	}
	return p;
}

//在第i个元素前插入值为e的新结点
/**
算法步骤:
1.首先找到ai-1的存储位置p
2.生成一个数据域为e的新结点s
3.插入新结点:
	新节点的指针域指向结点ai
	结点ai-1的指针域指向新结点
**/
Status ListInsert_L(LinkList &L,int i,ElemType e)
{
	p=L;j=0;
	while(p&&j<i-1){p=p->next;++j;}//寻找第i-1个结点,p指向i-1结点
	if(!p||j>i){//i大于表长+1或者小于1,插入位置非法
		return error;
	}
	s=new LNode;s->data=e;//生成新结点s,将结点s的数据域设置为e
	s->next=p->next;
	p->next=s;
	return OK;
}

/**
删除第i个结点
算法步骤:
1.首先找到ai-1的存储位置p,保存要删除的ai的值
2.让p->next指向ai+1
3.释放结点ai的空间
**/
Status ListDelete_L(LinkList &L,int i,ElemType &e){
	p=L;j=0;
	while (p->next&&j<i-1){//寻找第i个结点,并令p指向其前驱
		p=p->next;
		++j;
	}
	if(!(p->next)||j>i-1)
	{
		return error;//删除位置不合理
	}
	q=p->next;//临时保存被删结点的地址以备释放
	p->next=q->next;//改变删除结点前驱的指针域
	e=q->data;//保存删除结点的数据域
	delete q;//释放删除结点的空间
	return OK;
}

建立单链表:头插法-元素插入链表头部,也叫前插法

1.从一个空表开始,重复读入数据

2.生成新结点,将读入数据存放到新结点的数据域中

3.从最后一个结点开始,依次将各结点插入到链表的前端

复制代码
void CreateList_H(LinkList & L,nt n)
{
	L=new LNode;
	L->next=NULL;//先建立一个带头结点的单链表
	for(i=n;i>0;--i)
	{
		p=(LNode*)malloc(sizeof(LNode));//生成新结点
		scanf(&p->data)//输入元素值
		p->next=L->next;//插入到表头
		L->next=p;
	}
}

建立单链表:尾插法-元素插入链表尾部,也叫尾插法

1.从一个空表L开始,将新结点逐个插入到链表的尾部,尾指针r指向链表的尾结点

2.初始时,r同L均为头结点,每读入一个数据元素则申请一个新结点,将新结点插入到尾结点后,r指向新结点


循环链表:是一种首尾相接的链表(表中最后一个结点的指针域指向头结点,整个链表形成一个环 )

相关推荐
CoovallyAIHub6 小时前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
NAGNIP7 小时前
Serverless 架构下的大模型框架落地实践
算法·架构
moonlifesudo7 小时前
半开区间和开区间的两个二分模版
算法
moonlifesudo7 小时前
300:最长递增子序列
算法
CoovallyAIHub12 小时前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
CoovallyAIHub12 小时前
英伟达ViPE重磅发布!解决3D感知难题,SLAM+深度学习完美融合(附带数据集下载地址)
深度学习·算法·计算机视觉
聚客AI1 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v1 天前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工1 天前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农1 天前
【React用到的一些算法】游标和栈
算法·react.js