【数据结构】线性表——顺序表

news2024/11/26 10:40:35

文章目录

  • 一、线性表
  • 二、顺序表
    • 2.1概念及结构
    • 2.2、顺序表接口实现
      • 2.2.1、顺序表的动态存储
      • 2.2.2、顺序表初始化
      • 2.2.3、检查空间判断进行增容
      • 2.2.4、顺序表尾插、尾删
      • 2.2.5、顺序表头插、头删
      • 2.2.6、顺序表查找
      • 2.2.7、顺序表在pos位置插入x
      • 2.2.8、顺序表删除pos位置的值
      • 2.2.9、顺序表销毁
      • 2.2.10、顺序表打印
  • 三、顺序表的劣势


一、线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…

线性表逻辑上是线性结构,也就说是连续的一条直线(如图一)。但是在物理结构上并不一定连续的(如图二)。线性表物理上存储时,通常以数组和链式结构的形式存储。(假设在32位机器上)
在这里插入图片描述
在这里插入图片描述


二、顺序表

2.1概念及结构

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改

顺序表一般可以分为:

  1. 静态顺序表:使用定长数组存储元素。(如下图)在这里插入图片描述

  2. 动态顺序表:使用动态开辟的数组存储。在这里插入图片描述

说白了顺序表就是数组😆没想到把~意不意外
虽说顺序表就是数组,但是也不能说顺序表没用,在高级的储存单元里面(如二叉树)底层就是使用顺序表的。

2.2、顺序表接口实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

2.2.1、顺序表的动态存储

函数命名规则借鉴CPP的stl库进行命名。

首先创建一个结构体,用于储存顺序表结构。

typedef int SLDateType;
typedef struct SeqList
{
	SLDateType* a;
	int size;
	int capacity;
}SeqList;
  • typedef int SLDateType;把顺序表结构的类型重命名为:SLDateType。若将来如果要改变数据顺序表内容的结构类型。可以极为方便的改变。
  • 在结构体中定义了。顺序表的总体大小和当前容量。以便确认是否需要扩容。
  • 定义的SLDateType*用于接收动态开辟的内存。
  • size是顺序表的大小。
  • capacity是顺序表当前的元素数量。

2.2.2、顺序表初始化

void SeqListInit(SeqList* ps) {
	
	SLDateType* arr = (SLDateType*)malloc(sizeof(SLDateType) * 2);
	if (arr == NULL) {
		perror("malloc in SeqListInit of arr::");
	}
	ps->a = arr;
	ps->size = 2;
	ps->capacity = 0;
}
  • 因为顺序表的结构体是没有进行内存划分的。所以需要把顺序表的结构体进行初始化。
  • 默认开辟两个空间。
  • 在成功开辟后。把size设置为2。capacity设置为0。

2.2.3、检查空间判断进行增容

void CheckCapacity(SeqList* ps) {
	if (ps->capacity == ps->size) {
		SLDateType* arr = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * ps->size * 2);
		if (arr == NULL) {
			perror("realloc in SeqListPushBack");
		}
		ps->a = arr;
		ps->size *= 2;
	}
}
  • 每次进行插入都需要判断空间是否足够,所以,需要提前完成检查空间函数。
  • 每次扩容扩二倍。

2.2.4、顺序表尾插、尾删

void SeqListPushBack(SeqList* ps, SLDateType x) {
	assert(ps);
	CheckCapacity(ps);
	//int i = ps->capacity;
	(ps->a)[ps->capacity] = x;
	ps->capacity++;
}
  • 与数组的插入,并无二意。
void SeqListPopBack(SeqList* ps) {
	assert(ps && ps->capacity);
	ps->capacity--;
}
  • 只要把当前数据。进行减减。无需把顺序表中的内容进行删除。因为再次尾插数据,就会把之前的数据覆盖。

2.2.5、顺序表头插、头删

void SeqListPushFront(SeqList* ps, SLDateType x) {
	assert(ps);

	CheckCapacity(ps);


	memmove(((ps->a) + 1), ps->a, sizeof(SLDateType) * ps->capacity);
	ps->a[0] = x;
	ps->capacity++;
}
  • 顺序表的头插需要把全部数据往后移动一位。
  • 移动完成后就插入数据到头部空位。
void SeqListPopFront(SeqList* ps) {
	assert(ps && ps->capacity);
	ps->capacity--;
	memmove(ps->a, ((ps->a) + 1), sizeof(SLDateType) * ps->capacity);
}
  • 头删只需要把后面一位的数据全部往前移动一位。即可覆盖首元素的数据。

2.2.6、顺序表查找

int SeqListFind(SeqList* ps, SLDateType x) {
	assert(ps && ps->capacity);
	for (int i = 0; i < ps->capacity; i++) {
		if (ps->a[i] == x) {
			return i;
		}
	}
	return -1;
}
  • 与数组查找数据一样,循环遍历即可。

2.2.7、顺序表在pos位置插入x

void SeqListInsert(SeqList* ps, int pos, SLDateType x) {
	assert(ps && ps->capacity);

	CheckCapacity(ps);

	memmove(ps->a + pos, ps->a + pos - 1, sizeof(SLDateType) * (ps->capacity - pos + 1));
	ps->a[pos - 1] = x;
	ps->capacity++;
}
  • 找到对应位置后,从当前位置位置到数据结尾的内容全部向后移动一位。然后再在该位置进行数据的赋值。

2.2.8、顺序表删除pos位置的值

void SeqListErase(SeqList* ps, int pos) {
	assert(ps && ps->capacity);
	memmove(ps->a + pos - 1, ps->a + pos, sizeof(SLDateType) * (ps->capacity - pos + 1));
	
	ps->capacity--;

}
  • 找到需要删除的pos位置后。把pos后一位的内容全部向前移动一位即可把pos值原先的内容覆盖。做到删除pos位置的值

2.2.9、顺序表销毁

void SeqListDestroy(SeqList* ps) {
	assert(ps && ps->a);
	free(ps->a);
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}
  • 直接把动态开辟的内存释放掉,然后再把ps结构体中全部内容赋为空或零值。

2.2.10、顺序表打印

void SeqListPrint(SeqList* ps) {
	assert(ps && ps->a);
	for (int i = 0; i < ps->capacity; i++) {
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}
  • 与数组的循环打印并无二样。
  • 把循环结束条件定为capacity,这样做可以把尾删的数据不再打印数据中。

三、顺序表的劣势

  1. 中间/头部的插入删除,时间复杂度为O(N)
  2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
  3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

以上就是本章所有内容。若有勘误请私信不才。万分感激💖💖 如果对大家有帮助的话,就请多多为我点赞收藏吧~~~💖💖
请添加图片描述

ps:表情包来自网络,侵删🌹

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2235079.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

stable diffusion 大模型

本节内容&#xff0c;给大家带来的是stable diffusion的基础模型课程。基础模型&#xff0c;我们有时候也称之为大模型。在之前的课程中&#xff0c;我们已经多次探讨过大模型&#xff0c;并且也见识过一些大模型绘制图片的独特风格&#xff0c;相信大家对stable diffusion大模…

ChatPaper.ai:研究生文献阅读的AI助手利器

为什么选择 ChatPaper.ai&#xff1f; 作为研究生&#xff0c;我们每天都面临着大量文献阅读的挑战。一篇关键论文往往需要反复阅读数小时&#xff0c;还要做笔记、提取要点、理解创新点&#xff0c;这个过程既耗时又费力。ChatPaper.ai&#xff08;ChatPaper.ai - Chat with …

python-docx -- 读取word图片

文章目录 概念介绍形状对象读取图片自定义图形 概念介绍 从概念上来讲&#xff0c;word文档分为两层&#xff0c;一个文本层&#xff0c;一个绘画层&#xff1b; 文本层&#xff0c;从上到下&#xff0c;从左到右&#xff0c;流式排版&#xff0c;本页填满则开启新页面&#…

Python邮差:如何用代码精确投递商品快递费用的密信

目录 一、准备工作 二、编写API请求脚本 三、解析与处理快递费用数据 四、案例应用&#xff1a;模拟电商平台的快递费用计算 五、自动化邮件通知 六、总结 在电子商务的广阔天地里&#xff0c;精确计算并快速传递商品快递费用是一项至关重要的任务。作为Python邮差&#…

swoole扩展安装--入门篇

对于php来说&#xff0c;swoole是个强大的补充扩展。这是我第3次写swoole扩展安装&#xff0c;这次基于opencloudos8系统&#xff0c;php使用8.2。 安装swoole扩展首先想到的是用宝塔来安装&#xff0c;毕竟安装方便&#xff0c;还能统一管理。虽然获得swoole版本不是最新的&am…

Linux信号_信号的保存

我们知道向进程发送信号&#xff0c;进程并不是立即处理&#xff0c;而是等合适的时机进行处理。那么就需要保存信号。在信号的产生中说过信号保存在进程PCB里面的信号位图里&#xff0c;那信号位图到底是什么&#xff1f; 一.信号保存 我们先补充一些概念 1.阻塞 忽略概念 实…

如何使用示波器测量信号强度

示波器是一种用于观察和分析电信号的电子测试仪器。它可以显示信号的波形、幅度、频率和其他特性&#xff0c;是工程师和技术人员进行电路设计、调试和故障排除的重要工具。本文将详细介绍如何使用示波器测量信号强度。 一、认识示波器的基本组成部分 显示屏&#xff1a;用于显…

Axure设计之三级联动选择器教程(中继器)

使用Axure设计三级联动选择器&#xff08;如省市区选择器&#xff09;时&#xff0c;可以利用中继器的数据存储和动态交互功能来实现。下面介绍中继器三级联动选择器设计的教程&#xff1a; 一、效果展示&#xff1a; 1、在三级联动选择器中&#xff0c;首先选择省份&#xff…

K8S篇(基本介绍)

目录 一、什么是Kubernetes&#xff1f; 二、Kubernetes管理员认证&#xff08;CKA&#xff09; 1. 简介 2. 考试难易程度 3. 考试时长 4. 多少分及格 5. 考试费用 三、Kubernetes整体架构 Master Nodes 四、Kubernetes架构及和核心组件 五、Kubernetes各个组件及功…

卖模版还能赚到钱吗?

说到赚钱&#xff0c;我想大部分人都会感兴趣。但如果告诉大家现阶段卖模板也能赚钱&#xff0c;可能还是有人不信。我要说说我的观察了。 本文可在公众号「德育处主任」免费阅读 我是一只临期程序猿&#xff0c;我最早接触到“模板能卖钱”这个概念是在模板王里。模板王平台上…

超萌!HTMLCSS:打造趣味动画卡通 dog

这段HTML与CSS代码实现了一个超萌的动画卡通dog。 HTML <div class"dog"><div class"dog-body"><div class"dog-tail"><div class"dog-tail"><div class"dog-tail"><div class"do…

Elasticsearch Interval 查询:为什么它们是真正的位置查询,以及如何从 Span 转换

作者&#xff1a;来自 Elastic Mayya Sharipova 解释 span 查询如何成为真正的位置查询以及如何从 span 查询过渡到它们。 长期以来&#xff0c;Span 查询一直是有序和邻近搜索的工具。这些查询对于特定领域&#xff08;例如法律或专利搜索&#xff09;尤其有用。但相对较新的 …

【YOLOv11[基础]】实例分割Seg | 导出ONNX模型 | ONN模型推理以及检测结果可视化 | python

本文将导出YOLO-Seg.pt模型对应的ONNX模型,并且使用ONNX模型推理以及结果的可视化。话不多说,先看看效果图吧!!! 目录 一 导出ONNX模型 二 推理及检测结果可视化 1 代码 2 效果图

手搓AI大模型应用获25万用户,果断辞职创业,结果收入不如摆摊

我开发的 AI 应用有 25 万用户&#xff0c;我感觉要起飞了&#xff0c;于是辞掉工作&#xff0c;准备大干一番。 结果没想到开局即巅峰&#xff0c;突然就完蛋了。 这几天&#xff0c;一个悲催的程序员创业故事在社交网络上流传&#xff0c;引发了人们的深思。 故事的主人公&…

品质生活新选择:看三星AI神黑钻衣物护理机,如何为用户打造精致日常

屠格涅夫曾说&#xff0c;一个人应当好好地安排生活&#xff0c;要使每一刻的时光都有意义。这不仅是对个人生活的深刻洞察&#xff0c;也是对生活品质的不懈追求。实际上&#xff0c;在追求品质生活的道路上&#xff0c;无关乎年龄和阶层&#xff0c;其核心精髓往往潜藏于那些…

ios打包文件上传App Store windows工具

在苹果开发者中心上架IOS APP的时候&#xff0c;在苹果开发者中心不能直接上传打包文件&#xff0c;需要下载mac的xcode这些工具进行上传&#xff0c;但这些工具无法安装在windows或linux电脑上。 这里&#xff0c;我们可以不用xcode这些工具来上传&#xff0c;可以用国内的香…

Nginx(编译)+Lua脚本+Redis 实现自动封禁访问频率过高IP

1.安装lua 1.1安装LuaJIT yum install readline-devel mkdir -p lua-file cd lua-file/ wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz tar -zxvf LuaJIT-2.0.5.tar.gz cd LuaJIT-2.0.5 make && make install PREFIX/usr/local/luajit 1.2配置LuaJIT环境变量…

OA项目 python + vue3

准备工作 创建django项目 在setting.py进行数据库的配置&#xff1a; DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: , #数据库名字USER: , #连接的数据库的用户名PASSWORD: ,HOST: 127.0.0.1,PORT: 3306,} }安装app&#xff1a; rest_framwork: 关闭csrf…

内网渗透-信息收集篇

通过webshell或其他方式拿下一台机器&#xff0c;并且存在内网环境&#xff0c;这个时候就在准备进行内网渗透&#xff0c;而在内网渗透之前需要对本地机器进行信息收集&#xff0c;才能够更好的进行内网渗透。 目录 Windows本地基础信息收集 权限查看 判断域存在 查看防火…

斯坦福团队研发:手机运行的超GPT-4大模型一夜爆红,下载量突破2000次

在大模型落地应用的过程中&#xff0c;端侧 AI 是非常重要的一个方向。 近日&#xff0c;斯坦福大学研究人员推出的 Octopus v2 火了&#xff0c;受到了开发者社区的极大关注&#xff0c;模型一夜下载量超 2k。 20 亿参数的 Octopus v2 可以在智能手机、汽车、个人电脑等端侧…