【C语言之线性表链式存储结构】

2023-05-16

C语言之线性表链式存储结构

文章目录

  • C语言之线性表链式存储结构
  • 前言
  • 一、线性表链式存储结构定义
  • 二、相关概念
    • 1.结点
    • 1.头指针
  • 三、代码描述
    • 1.单链表结点定义
    • 1.单链表的创建
    • 2.单链表的查找
    • 3.在单链表中,替换某一个位置的数据
    • 4.在单链表中,某一个位置插入数据
    • 4.在单链表中,某一个位置删除数据


前言

线性表存在不足的解决办法:`
线性表最大的缺点就是插入和删除时需要移动大量元素,这需要耗费大量时间;因此就引出链式存储结构,用任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续。
在这里插入图片描述


一、线性表链式存储结构定义

定义:
以前顺序结构中,每个数据元素只需要存数据元素就可以了,但链式结构中,为了将链表连接起来,每个元素不仅要存储数据元素信息,还需要存储它的后继元素的存储地址。
在这里插入图片描述

二、相关概念

1.结点

链表结点由数据域(存放本身信息)和指针域(指向后继结点的指针)构成。如下图所示:
在这里插入图片描述

1.头指针

对于线性表来说,总得有个头有个尾,链表也不例外,我们把链表中的第一个结点的存储位置叫做头指针,整个链表的存取就必须是从头指针开始进行了。
最后一个结点的指针为空(NULL)。
有时候我们为了更方便的对链表进行操作,会在单链表的第一个结点前附设一个结点,称为头结点。
头结点的数据域可以不存储任何信息,也可以存储如线性表长度等附加信息。
在这里插入图片描述
空链表:
在这里插入图片描述

带头结点的单链表:
在这里插入图片描述
不带头结点的单链表:
在这里插入图片描述

三、代码描述

1.单链表结点定义

typedef int ElemType;可以随着数据元素类型不用,自己定义
链表的结构体
struct Node
{
	ElemType data;
	struct Node* next;
}Node;

typedef  struct Node* LinkList;链表指针别名

总这个结构定义中,我们也可以知道,结点由存放数据元素的数据域和存放后继结点地址的指针域组成。假设p是指向线性表第i个元素的指针,则该结点ai的数据域,可以用p->data来表示,结点ai的指针域,可以用p->next来表示。p->next指向(意思就是存储第i个元素的地址)第i+1个元素。也就是说,如果p->data=ai,p->next->data=ai+1;
在这里插入图片描述


1.单链表的创建

单链表创建算法思路:

  • 初始化空链表L-创建头结点
  • 声明中间变量指向头结点,用于遍历链表
  • 循环
  • 生成新的结点
  • 新的结点指针指向头结点(指针)
  • 头结点指针指向新结点
头插法
LinkList CreatListHead(int len)
{
	LinkList L = (LinkList)malloc(sizeof(Node));//创建个头节点
	LinkList temp=L;                   //声明一个中间变量,指向头结点,用于遍历链表(曾因没有这个中间变量而出错)
	temp->next = NULL;

	for (int i=0;i<len;i++)
	{
		LinkList p= (LinkList)malloc(sizeof(Node)); 
		scanf_s("%d",&p->data);
		p->next = temp->next;     //新结点的next指针,指向开始结点(temp->next是头结点的地址)
		temp->next = p;                //头结点的next指针指向新结点
	}
	return (LinkList)L;
}

在这里插入图片描述
解释说明:p->next是下一个结点指针的地址
p是结点指针

尾插法

链表的创建,建立带头节点的单链线性表L,随机产生N个元素值
LinkList CreatListTail(int len)
{
	LinkList L = (LinkList)malloc(sizeof(Node));创建个头节点
	LinkList temp = L;                   声明一个中间变量,指向头结点,用于遍历链表(曾因没有这个中间变量而出错)
	temp->next = NULL;
	for (int i = 0; i < len; i++)
	{
		LinkList p = (LinkList)malloc(sizeof(Node));
		scanf_s("%d", &p->data);
		temp->next = p;   头结点指向新的结点(存储新结点地址)
		temp = p;                将新结点变成头结点等待下一个新结点插入
	}
	temp->next = NULL;将最后一个结点的NEXT结点为空,表示链表结束
	return (LinkList)L;
}

2.单链表的查找

因为链表不支持随机访问,即链表的存取方式是顺序存取的(注意“存储”与“存取”是两个不一样的概念),所以要查找某结点,必须通过遍历的方式查找。例如:如果想查找第3个结点,必须先遍历走过第1~2个结点,才能得到第3个结点。
单链表查找算法思路:

  • 链表存在,输入要查找的值
  • 声明中间变量指向头结点,用于遍历链表
  • 循环
  • 指针后移遍历链表
  • 将链表中与查找值相等的数据返回
int SearchList(LinkList L,int elem)
{
	LinkList temp;
	temp = L;
	int position = 0;用于返回数据在链表中的位置
	while (temp->next)
	{   
		position++;
		temp = temp->next;指针后移遍历链表
		if (elem == temp->data)
		{
			printf_s("Searchdata=%d,postion=%d\n", temp->data, position);
		}
		return position;
	}
	return 0;
}

3.在单链表中,替换某一个位置的数据

单链表替换算法思路:

  • 链表存在,输入要替换的位置,要替换的数值
  • 声明中间变量指向头结点,用于遍历链表
  • 循环
  • 指针后移遍历链表,到要替换的位置,跳出循环
  • 将要替换的值,赋值到数据域
  • 返回链表的头结点
LinkList  ReplaceList(LinkList L,int pos,int elem)
{
	LinkList temp = L;
	temp = temp->next;指向开始结点(注意头结点与开始结点区别)头结点的后继结点为开始结点
	for (int i = 0; i < pos; i++)
	{
		temp = temp->next;
	}
	temp->data = elem;
	return L;
}

4.在单链表中,某一个位置插入数据

单链表插入算法思路:

  • 链表存在,输入要插入的位置,要插入的数值
  • 声明中间变量指向头结点,用于遍历链表
  • 循环
  • 指针后移遍历链表,找到插入位置前的结点
  • 新建结点,将要插入的数据,赋值到新建结点的数据域
  • 返回链表的头结点
    在这里插入图片描述
LinkList InsertList(LinkList L,int pos,int elem)
{
	LinkList temp = L;
	int i = 0;
	temp = temp->next;指向开始结点

	for (i = 0; i < pos-1; i++)
	{
		if ((temp == NULL) || (i > pos - 1))
		{
			printf("%s:Insert false!\n", __FUNCTION__);
			return L;
		}
		temp = temp->next;
	}
	LinkList new = (LinkList)malloc(sizeof(Node));
	new->data = elem;
	new->next = temp->next;新建结点指向插入的下个结点
	temp->next = new;插入位置的结点指针指向新建结点
	return L;

}
第二种写法

LinkList InsertList(LinkList L, int pos, int elem)
{
	LinkList temp = L;	//引入一个中间变量,用于循环变量链表
	int i = 0;
	/* 首先找到插入结点的上一结点,即第pos-1个结点 */
	while( (temp!=NULL)&&(i<pos-1) )
	{
		temp = temp->next;
		++i;
	}
	/* 错误处理:链表为空或插入位置不存在 */
	if( (temp==NULL)||(i>pos-1) )		
	{
		printf("%s:Insert false!\n",__FUNCTION__);
		return (LNode*)temp;
	}
	LinkList new = (LinkList)malloc(sizeof(Node));	//创建新结点new
	new->data = elem;		插入的新结点的数据域
	new->next = temp->next; 新结点的next指针指向插入位置后的结点
	temp->next = new;		插入位置前的结点的next指针指向新结点
	return L;返回头结点

4.在单链表中,某一个位置删除数据

单链表插入算法思路:

  • 链表存在,输入要插入的位置,要插入的数值
  • 声明中间变量指向头结点,用于遍历链表
  • 循环
  • 指针后移遍历链表,找到插入位置前的结点
  • 新建结点,将要插入的数据,赋值到新建结点的数据域
  • 返回链表的头结点
    在这里插入图片描述
LinkList DeleteList(LinkList L, int pos, int *elem)
{
	LinkList temp = L;
	int i = 0;
	temp = temp->next;指向开始结点
	LinkList del;新建结点

	for (i = 0; i < pos - 1; i++)
	{
		if ((temp == NULL) || (i > pos - 1))
		{
			printf("%s:Insert false!\n", __FUNCTION__);
			return L;
		}
		temp = temp->next;
	}

	del = temp->next; 结点指向被删除结点
	*elem = del->data; 结点数据域存储到elem中
	temp->next = del->next;要删除位置前的结点指向要删除结点后的结点
	free(del);释放内存
	del = NULL;防止野指针
	return L;

}
第二种写法

LinkList Delete(LinkList L, int pos, int *elem)
{
	LinkList temp = L;	//引入一个中间变量,用于循环变量链表
	int i = 0;
	/* 首先找到删除结点的上一结点,即第pos-1个结点 */
	while( (temp!=NULL)&&(i<pos-1) )
	{
		temp = temp->next;
		++i;
	}
	/* 错误处理:链表为空或删除位置不存在 */
	if( (temp==NULL)||(i>pos-1) )
	{
		printf("%s:Delete false!\n",__FUNCTION__);
		return temp;
	}
	LinkList del = temp->next;	//定义一个del指针指向被删除结点
	*elem = del->data;			//保存被删除的结点的数据域
	temp->next = del->next;		/*删除结点的上一个结点的指针域指向删除结点的下一个结点,
								  也可写为“temp->next = temp->next->next”*/
	free(del);					//手动释放该结点,防止内存泄露
	del = NULL;					//防止出现野指针
	return L;			

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C语言之线性表链式存储结构】 的相关文章

  • 【学习笔记】GPS原理与数据处理(相对定位)

    一 基本概念 1 相对定位 确定同步跟踪相同的GPS卫星信号的若干台接收机之间的相对位置 xff0c 即坐标差 相对位置用一条基线向量表示 xff0c 故相对定位有时也称测定基线向量或者基线测量 2 静态定位 待定点在地固坐标系中的位置没有
  • 【学习笔记】GPS原理与数据处理(静态定位模糊度的固定)

    一 静态定位中常用的方法 经典的静态定位常被用于高精度的GPS测量领域 xff0c 一般进行较长时间的观测 xff0c 以便能获得精确的实数模糊度 xff08 其误差小于0 1周 xff09 取整法 对求出的模糊度进行四舍五入 xff0c
  • qt中QList使用removeAt()删除元素

    提要 QList删除元素的时候需要特别注意一点 xff0c 将元素删除后链表中元素的排列 删除一个元素后 xff0c 后面的元素会补到被删元素的位置 xff0c 这样在for循环中若删除元素后继续执行下标 43 43 xff0c 则会少遍历
  • Ubuntu20.04下的编译与运行LeGO-LOAM【问题解决】

    LeGO LOAM在Ubuntu20 04下编译和运行的问题 一 OpenCV 版本问题二 pcl问题1 C 43 43 14环境2 报错 xff1a Index is not a member of Eigen 三 usr bin ld问
  • ubuntu 20.04 安装 ceres库

    文章目录 一 安装依赖项二 下载源码 xff1a 三 编译并且安装1 进入正确位置 xff1a 2 建立build xff0c 并进入3 编译4 安装 安装完成后是下面这个界面 xff1a 一 安装依赖项 sudo apt span cla
  • ROSERROR : CMake Error at /opt/ros/noetic/share/pcl_ros/cmake/pcl_rosConfig.cmake:113 (message)

    文章目录 问题如下 xff1a 产生问题分析 xff1a 解决办法 xff1a 效果 xff1a 问题如下 xff1a 产生问题分析 xff1a 由于之前eigen库与ceres库的冲突 xff0c 进行了两个库的重装并删除了相关文件夹 x
  • Ubuntu20.04下的编译与运行LIO-SAM【问题解决】

    LIO SAM在Ubuntu20 04下编译和运行的问题 一 安装依赖项1 Boost gt 61 1 652 CMake gt 61 3 03 gcc大于4 7 3就行4 安装 TBB5 安装 MKL 二 安装GTSAM三 OpenCV
  • 在Ubuntu20.04系统上LIO-SAM跑KITTI数据集和自己数据集代码修改

    LIO SAM跑KITTI数据集和自己数据集代码修改 一 编译并运行LIO SAM二 代码修改1 cloud info msg2 imageProjection cpp 三 KITTI数据集准备四 自己数据集准备五 修改配置文件params
  • KITTI数据集Raw Data与Ground Truth序列00-10的对应关系,以及对应的标定参数

    一 KITTI官方提供的真值和标定参数下载地方 网站 xff1a Visual Odometry SLAM Evaluation 2012 具体位置 xff1a 真值 xff1a Download odometry ground truth
  • 相机内参标定,相机和激光雷达联合标定

    相机内参标定 xff0c 相机和激光雷达联合标定 一 相机标定原理1 1 成像过程1 2 标定详解 二 相机和激光雷达联合标定2 1 标定方法汇总2 2 Autoware的安装与运行2 2 1 安装方式2 2 2 安装Autoware的依赖
  • Ubuntu20.04安装和编译运行lidar_align来联合标定lidar与imu的外参

    Ubuntu20 04安装和编译运行lidar align来联合标定lidar与imu的外参 一 编译运行lidar align1 1 下载地址1 2 编译1 2 1 nlopt问题解决1 2 2 c 43 43 问题解决 二 处理数据集三
  • ROS小工具学习与使用

    ROS小工具学习与使用 rqt的使用 rqt bag工具 rqt bag span class token operator lt span your bagfile span class token operator gt span sp
  • printf函数的实现方法

    printf是一个C库函数 xff0c 用于向标准输出 xff08 stdout xff09 写入格式化的字符串 如果格式字符串包含格式说明符 xff08 以 开头的子序列 xff09 xff0c 则需要额外的参数来替换相应的说明符 实现p
  • linux下查看cmake的版本

    方法 在命令行输入指令 xff1a cmake span class token operator span version
  • C++常用标准库

    STL是Standard Template Library的简称 xff0c 中文名标准模板库 从根本上说 xff0c STL是一些 容器 的集合 xff0c 这些 容器 有list vector set map等 xff0c STL也是算
  • 如何轻松写出正确的链表代码

    如何轻松写出正确的链表代码 xff1f 1 理解指针或引用的含义 将某个变量赋值给指针 xff0c 实际上就是将这个变量的地址赋值给指针 xff0c 或者反过来说 xff0c 指针中存储了这个变量的内存地址 xff0c 指向了这个变量 xf
  • JVM之虚拟机栈详细讲解

    Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域 这些区域有各自的用途 xff0c 以及创建和销毁的时间 xff0c 有的区域随着虚拟机进程的启动而一直存在 xff0c 有些区域则是依赖用户线程的启动和结
  • 【图像处理】特征点算法整理总结

    特征点检测 1 Susan SUSA xff08 Smallest Univalue Segment Assimilating Nucleus xff09 算子是一种高效的边缘和角点检测算子 xff0c 并且具有结构保留的降噪功能 原理 用
  • 图像特征点匹配算法

    sift https blog csdn net weixin 38404120 article details 73740612 https blog csdn net abcjennifer article details 763968
  • 算法目标检测面经

    1 自我介绍 2 简历上的项目 网易雷火 AI研究员 1 ResNet FCN Fasterrcnn 2 膨胀腐蚀的原理 3 均值滤波的原理 时间复杂度 怎么优化 4 第k大的数 topK个数 网易互娱预研 深度学习计算机视觉 1 语义分割

随机推荐

  • 图像配准(Image Registration)简介

    图像配准在目标检测 模型重建 运动估计 特征匹配 xff0c 肿瘤检测 病变定位 血管造影 地质勘探 航空侦察等领域都有广泛的应用 每一种配准方法通常都针对某个具体问题而设计的 xff0c 众多方法中 xff0c 唯一的共性就是每个配准问题
  • SSD算法详解

    转载 xff1a https blog csdn net ytusdc article details 86577939 SSD github https github com weiliu89 caffe tree ssd SSD pap
  • 深度学习-目标检测评估指标P-R曲线、AP、mAP

    基本概念 P R曲线中 xff0c P为图中precision xff0c 即精准度 xff0c R为图中recall xff0c 即召回率 Example 下面通过具体例子说明 首先用训练好的模型得到所有测试样本的confidence s
  • 使用gitlab初次上传代码

    提要 项目开发中需要使用gitlab来管理代码 xff0c 将自己开发的模块上传到gitlab 第一次使用这个代码管理仓库 xff0c 记录一下 方法 1 首先注册gitlab的账号 这个在百度上搜一下gitlab的官网 xff0c 进去后
  • Keil5添加.c文件与.h文件的方法-导入支持库-新大陆物联网竞赛-Lora模块&NBIOT模块例程-添加导入文件

    一 概述 在某些情况下 xff0c 我们使用现用的物联网开发例程 xff0c 例如新大陆物联网的Lora与NBIOT的例程 xff0c 我们对其例程内目前所有的库不满意 xff0c 不足以实现开发需要的功能 xff0c 我们需要在原有工程上
  • 初探DSO-SLAM并运行dso_ros

    最近在做SLAM相关的工作 xff0c 用思岚的A2激光雷达在turtlebot3上测试SLAM建图效果 xff0c 感觉还是不错的 由于项目在方案上还没有确定选择哪种作为SLAM的最终方案 xff0c 在我测试奥比中光ASTRA mini
  • 虚拟机中安装CMake工具

    https www cnblogs com yanqingyang p 12731855 html
  • 寻路系统:动态障碍物

    寻路的相关参数 需要先勾选 游戏场景中所有需要烘焙路径信息的游戏对象状态为 static 然后点开windos菜单下的navigation窗口进行烘培 Navigation Static xff1b 表示该游戏对象是否参与导航网格的烘培 G
  • Ubuntu18.04下使用cmake编译一个OpenCV程序(编写CMakeLists.txt文件)

    导航 1 安装OpenCV1 1首先安装OpenCV 1 2定位OpenCV 2 创建一个项目3 编写一个基础OpenCV程序4 编写CMakeLists txt文件 为了记录以及防止遗忘 xff0c 备份一个大致能满足运行的CMakeLi
  • linux下最全curl命令使用方式学习和拓展

    为什么要使用curl命令 xff1f curl命令可以帮助我们在linux服务内部通讯 xff0c 排查接口是否能够正确调用 xff0c 外网的接口是否有防火墙限制 xff0c 内网的请求可以快速帮我们获取接口参数返回 xff0c 并且调试
  • 【传感器标定】kalibr 标定工具箱问题汇总

    文章目录 写在前面一 运行一段时间报错 96 Spline Coefficient Buffer Exceeded Set larger buffer margins 96 的解决方法1 问题描述2 解决方法参考链接 写在前面 kalibr
  • C++中的Vector存放指针的清空问题

    C 43 43 中的Vector存放指针的清空问题 一 写在前面二 参考做法参考链接 这两个链接写得挺好 xff0c 可以参考下 一 写在前面 C 43 43 很难的一个重要原因就是内存管理的问题 xff0c 因为你既要管理申请内存 xff
  • find_package(xxxx REQUIRED)找不到路径的全平台通用解决办法

    相信刚学cmake c 43 43 的朋友们在编译的时候一定被这个问题折磨许久哈 然后怎么搜怎么添加都有问题 xff0c 仔细研究了我才发现这个地方不同的索引机制 xff0c 但是表面上都是 find package xxxx REQUIR
  • STC51-串口通信

    1 并行与串行基本通信方式 随着单片机系统的广泛应用和计算机网络技术的普及 xff0c 单片机的通信功能愈来愈显得重要 单片机通信是指单片机与计算机或单片机与单片机之间的信息交换 xff0c 通常单片机与计算机之间的通信我们用的较多 通信有
  • qt种实现搜索栏功能

    引言 在搜索栏种输入要搜索的文本 xff0c 就会出现相关联的文本提示 xff0c 这是可以通过鼠标选中要搜索的文本 xff0c 或者通过上下键选中要搜索的文本 效果 效果图如下所示 xff1a 实现 下面是相关的代码实现 xff0c 读者
  • orangePi3 TLS烧录启动、wifi配置和ssh登录、烧录进内置emmc flash

    orangePi3 TLS烧录启动 wifi配置和ssh登录 烧录进内置emmc flash 烧录镜像到TF卡启动 镜像下载 官方镜像地址 xff1a http www orangepi cn html hardWare computerA
  • C/C++——代码的编译和运行

    1 编译过程 每种高级语言都有对应的编译器 xff0c 而且针对不同指令集架构的CPU会提供不同的编译器 本文以C语言为例 xff0c CPU指令集架构不做前提约束 xff0c 实际上同一种语言也只有在狭义的编译阶段有所区别 xff0c 其
  • Arduino UNO GPS 制作 里程表 经纬度

    机缘 上过月买了一个GPS模块 xff0c 然后我用esp32读取GPS数据 xff0c 并使用LVGL显示GPS信息 期间踩了很多坑 xff0c 我用乐鑫的IDF开发 xff0c 自己写了一个GPS信息提取方法 xff0c BUG很多 x
  • socket编程——UDP协议(C语言编程)

    1 收发信息 ssize t sendto int socket void message size t length int flags struct sockaddr dest addr socklen t dest len 返回值 l
  • 【C语言之线性表链式存储结构】

    C语言之线性表链式存储结构 文章目录 C语言之线性表链式存储结构前言一 线性表链式存储结构定义二 相关概念1 结点1 头指针 三 代码描述1 单链表结点定义1 单链表的创建2 单链表的查找3 在单链表中 xff0c 替换某一个位置的数据4