[C][数据结构][顺序表]详细讲解+实现

目录

  • 1.线性表
  • 2.顺序表 - SeqList
  • 3.实现
  • 4.顺序表缺点


1.线性表

  • 线性表(linear list)是n个具有相同特性的数据元素的有限序列
  • 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
  • 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储

2.顺序表 - SeqList

  • 概念及结构

    • 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改 (此数组必须从第一个位置开始,连续存储)

    请添加图片描述

  • 动态顺序表 – 使用动态开辟的数组存储


3.实现

  • 接口
typedef int SLDataType;//类型重命名,方便以后维护替换别的类型
 
typedef struct SeqList
{
	SLDataType* arr;//指向动态数组指针
	int size;//有效数据个数
	int capacity;//容量 - 空间大小
}SL;
 
//顺序表初始化
void SLInit(SL* ps);
//销毁顺序表
void SLDestroy(SL* ps);
//打印顺序表
void SLPrint(SL* ps);
 
//检测增容
void SLCheckCapacity();
 
//增删查改
//尾插/尾删 - O(1)
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
 
//头插/头删 - O(N)
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
 
//从任意位置插入/删除
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
 
//查找和修改
int SLSearch(SL* ps, SLDataType x);
void SLModify(SL* ps, int pos, SLDataType x);
  • 接口实现
void SLInit(SL* ps)
{
	assert(ps);
 
	ps->arr = NULL;
	ps->size = 0;
	ps->capacity = 0;
}
 
void SLDestroy(SL* ps)
{
	assert(ps);
 
	if (ps->arr)
	{
		free(ps->arr);
		ps->arr = NULL;
		ps->capacity = 0;
		ps->size = 0;
	}
}
 
void SLPrint(SL* ps)
{
	assert(ps);
 
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->arr[i]);
	}
 
	printf("\n");
}
 
void SLCheckCapacity(SL* ps)
{
	assert(ps);
 
	//检查容量空间,满了扩容
	if (ps->size == ps->capacity)
	{
		ps->capacity = ps->capacity == 0 ? 4 : ps->capacity * 2; //最大容量扩容
		SLDataType* tmp = realloc(ps->arr, ps->capacity * sizeof(SLDataType));
		if (NULL == tmp)
		{
			perror("realloc:");
			exit(1);
		}
		ps->arr = tmp;
	}
}
 
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
 
	SLCheckCapacity(ps);
 
	ps->arr[ps->size] = x;
	ps->size++;
 
	//SLInsert(ps, ps->size, x); //以上代码可以用这个封装替换了
}
 
void SLPopBack(SL* ps)
{
	assert(ps);
	//暴力检查 - 适用于调试阶段
	assert(ps->size > 0);
 
	//温柔检查 - 适用于和用户交互使用
	//if (0 == ps->size)
	//{
	//	printf("SeqList is empty\n");
	//	return;
	//}
	
	ps->size--;
 
	SLErase(ps, ps->size - 1); //以上代码可以用这个封装替换了
}
 
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
 
	//挪动数据
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->arr[end + 1] = ps->arr[end];
		end--;
	}
 
	ps->arr[0] = x;
	ps->size++;
 
	//SLInsert(ps, 0, x); //以上代码可以用这个封装替换了
}
 
void SLPopFront(SL* ps)
{
	int begin = 1;
	while (begin < ps->size)
	{
		ps->arr[begin - 1] = ps->arr[begin];
		begin++;
	}
 
	ps->size--;
 
	//SLErase(ps, 0); //以上代码可以用这个封装替换了
}
 
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size); //检验位置合法性
 
	SLCheckCapacity(ps);
 
	//挪动数据
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->arr[end + 1] = ps->arr[end];
		end--;
	}
 
	ps->arr[pos] = x;
	ps->size++;
}
 
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
 
	//挪动数据
	int begin = pos;
	while (begin < ps->size - 1)
	{
		//后面的数据往前搬
		ps->arr[begin] = ps->arr[begin + 1];
		begin++;
	}
 
	ps->size--;
}
 
int SLSearch(SL* ps, SLDataType x)
{
	assert(ps);
	
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (ps->arr[i] == x)
		{
			return i;
		}
	}
 
	return -1;
}
 
void SLModify(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
 
	ps->arr[pos] = x;
}

4.顺序表缺点

  • 空间不够,需要扩容。
    • 扩容有一定性能损耗
    • 一般扩容两倍,存在一些空间浪费
  • 头部或者中间位置插入删除效率低下 – 挪动数据
  • 改善方案 – 链表 – 对顺序表缺陷的优化
    • 按需申请释放空间
    • 头部或者中间插入删除,不需要挪动数据

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

十.数据链路层——MAC/ARP

IP和数据链路层之间的关系 引言 在IP一节中&#xff0c;我们说IP层路由(数据转发)的过程&#xff0c;就像我们跳一跳游戏一样&#xff0c;从一个节点&#xff0c;转发到另一个节点 它提供了一种将数据从A主机跨网络发到B主机的能力 什么叫做跨网络&#xff1f;&#xff1f;&a…

Windows开启远程桌面

搜索并进入【远程桌面设置】 ​​ 开启远程桌面 ​​​ ipconfig​命令查看ip地址&#xff0c;并使用地址在另一台电脑远程登录此电脑 选择其他账户登录&#xff0c;输入用户和密码 ​​ ​​ 成功登录 ​​

AlDente Pro for Mac(电池最大充电限制工具)v1.24激活版

AlDente Pro for Mac是一款运行在MacOS平台上专业的电池最大充电限制工具。通过 AlDente Pro 您可以设置电池的最大充电百分比设置为 20&#xff05; 至 100&#xff05;&#xff0c;然后&#xff0c;它将保持在所需的电池百分比&#xff0c;然后再次使用电源适配器进行充电。 …

VM-Import 导入 Debian 12 系统

介绍 之前介绍过使用 VM-Import 导入 Windows 系统到 AWS 环境启动 EC2 实例, 本文将介绍如何导入 Debian 12 系统. 本地虚拟化使用 VMWare Workstation 创建虚拟机安装和准备 Debian 12 系统, 导出 OVA 文件后上传到 S3 存储桶中再使用 AWSCLI 执行 VM-Import 命令实现导入过…

设计模式-抽象工厂(创建型)

创建型-抽象工厂 角色 抽象工厂&#xff1a; 声明创建一个族产品对象的方法&#xff0c;每个方法对应一中产品&#xff0c;抽象工厂可以是接口&#xff0c;也可以是抽象类&#xff1b;具体工厂&#xff1a; 实现抽象工厂接口&#xff0c;复杂创建具体的一族产品&#xff1b;抽…

[移动通讯]【无线感知-P2】[特征,算法,数据集】

前言&#xff1a; 这里面主要参考清华大学的杨峥教授&#xff0c;做一下无线感知的总结. 基本思想&#xff1a; 无线信号不仅可以传输数据,还可以感知环境信号发射机产生的无线电波 经由直射,反射,散射等多条路径传播,在信号接收机形成的多径叠加信号 携带反映环境特征…

Unreal项目修改名字

Unreal项目修改名字 前言修改Unreal Blueprints工程项目名字修改Unreal C工程项目名字 前言 Unreal项目修改名字还是比较麻烦的&#xff0c;针对纯蓝图工程和C工程有一些区别。 修改Unreal Blueprints工程项目名字 修改纯蓝图的Unreal项目还是比较简单的&#xff0c;只要两个…

hcia datacom学习(12):vlan间路由

不同vlan相当于不同网段&#xff0c;如果vlan间没有三层技术&#xff0c;那么它们就无法互相通信。 vlan间路由可以有3种方式&#xff1a; 1.直接使用路由器转发 *路由器本身不需要额外设置&#xff0c;只需配置端口ip作为网关即可。 *路由器不能处理带有vlan标签的数据帧&a…

vulnhub靶机实战_DC-4

下载 靶机下载链接汇总&#xff1a;https://download.vulnhub.com/使用搜索功能&#xff0c;搜索dc类型的靶机即可。本次实战使用的靶机是&#xff1a;DC-4系统&#xff1a;Debian下载链接&#xff1a;https://download.vulnhub.com/dc/DC-4.zip 启动 下载完成后&#xff0c;…

【PL理论】(5) F#:递归类型 | Immutability 特性(F#中值一旦定义就不会改变)

&#x1f4ad; 写在前面&#xff1a;本文旨在探讨不可变数据结构在 F# 编程中的应用&#xff0c;特别是如何利用递归记录类型来表示和操作数值表达式。通过定义存储整数的二叉树和数值表达式的类型&#xff0c;我们将展示不可变性如何简化程序的理解和维护。文章将对比 F# 与命…

适合航天航空的国产FTP替代软件

在宇宙探索的旅程中&#xff0c;航空和航天领域总是站在科技的最前沿&#xff0c;对数据传输的要求特别高。随着信息量急剧增加和安全威胁的复杂化&#xff0c;传统的FTP软件已经不能满足这个高端领域的需要了。因此&#xff0c;找到一款适合航空和航天领域的FTP替代软件&#…

spring 解决循环依赖

在 spring 框架中&#xff0c;我们知道它是通过三级缓存来解决循环依赖的&#xff0c;那么它具体是怎么实现的&#xff0c;以及是否必须需要三级缓存才能解决循环依赖&#xff0c;本文来作相关介绍。 具体实现 先来看看它的三级缓存到底是什么&#xff0c;先看如下代码&#…

Nginx网站服务【☆☆☆】

市面上常用Linux的web服务器&#xff1a;apache、Nginx。 apache与nginx的区别&#xff1f; 最核心的区别在于NGINX采用异步非阻塞机制&#xff0c;多个连接可以对应一个进程&#xff1b;apache采用的是同步阻塞多进程/线程模型&#xff0c;一个连接对应一个进程。apache美国…

c++简略实现共享智能指针Shared_Ptr<T>

重点&#xff1a; 1.引用计数在堆上&#xff08;原本应为原子变量&#xff09; 2.引用计数增加减少需要加锁保证线程安全。 3.内部实现Release函数用于释放资源 4.未实现&#xff0c;增加自定义删除器可以将Release修改为模板函数&#xff0c;传入可调用参数。对于shared_p…

tomcat服务器之maxHttpHeaderSize

背景&#xff1a;在OA流程表单中&#xff0c;填写了200条数据&#xff0c;一提交&#xff0c;秒报400错误&#xff0c;且请求没有打到后端中&#xff08;无报错日志&#xff09;&#xff0c;一开始以为是谷歌浏览器的问题&#xff0c;可百度上关于这个错误的解决方案都是清除缓…

docker实战流程:

Docker-compose是docker官方的开源项目&#xff0c;负责实现对docker容器的集群的快速编排&#xff08;通过yaml文件docker-compose.yml管理写好容器之间的调用关系只需一个命令就能实现容器的通识开启或关闭&#xff09;。 类比spring容器&#xff0c;spring管理的是bean而do…

vue3+uniapp

1.页面滚动 2.图片懒加载 3.安全区域 4.返回顶部&#xff0c;刷新页面 5.grid布局 place-self: center; 6.模糊效果 7.缩放 8.微信小程序联系客服 9.拨打电话 10.穿透 11.盒子宽度 12.一般文字以及盒子阴影 13.选中文字 14.顶部安全距离 15.onLoad周期函数在setup语法糖执行后…

PVE安装虚拟主机

本文记录PVE安装其他虚拟主机的步骤&#xff0c;以安装win-server为例。裸机安装PVE则不是本文主题。 准备文件 获取Windows系统镜像 win server镜像可以从官网获取普通Windows镜像可从MSDN获取此外&#xff0c;安装Windows系统还需要从PVE下载特殊驱动 获取Windows必要驱动 …

数据库(25)——多表关系介绍

在项目开发中&#xff0c;进行数据库表结构设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;分析并设计表结构&#xff0c;各个表之间的结构基本上分为三种&#xff1a;一对多&#xff0c;多对多&#xff0c;一对一。 一对多 例如&#xff0c;一个学校可以有…

PromptPerfect:AI Prompt生成与优化专家

PromptPerfect&#xff1a;AI Prompt生成与优化专家 PromptPerfect是一款专业的AI Prompt生成与优化工具&#xff0c;旨在帮助用户解锁和最大化GPT-4、ChatGPT、Midjourney等先进AI模型的潜力。它通过智能生成和精细优化Prompt&#xff0c;帮助用户获得更精确、更相关、更高效…