顺序表(C语言详细版)

1. 线性表

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

线性表在逻辑上是线性结构,也就是说连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

2. 顺序表实现

2.1 概念及结构

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

顺序表一般可以分为:

1.静态顺序表:使用定长数组存储。

2.动态顺序表:使用动态开辟的数组存储。

#define N 100
// 静态顺序表
struct SeqList
{
	int arr[N];
	int size;	// 有效数据个数
};

typedef int SLDataType;

// 动态顺序表
typedef struct SeqList
{
	SLDataType* arr;
	SLDataType size;	// 有效数据个数
	SLDataType capacity;	// 空间大小
}SL;

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

2.2 顺序表初始化

// 顺序表初始化
void SLInit(SL* ps);

首先,我们需要初始化数组,数组首元素地址 ps->arr 置为NULL;有效数字个数 size 和空间容量capacity 大小都置为0。

// 顺序表初始化
void SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

2.3 顺序表销毁

// 顺序表销毁
void SLDestroy(SL* ps);

我们使用完顺序表之后,都需要把顺序表进行销毁,以免造成内存被占用和内存泄漏问题。

首先,需要把开辟的空间 free 掉,再将数组首元素地址 ps->arr 置为NULL;有效数字个数 size 和空间容量 capacity 大小都置为0。

// 顺序表销毁
void SLDestroy(SL* ps)
{
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

2.4 顺序表打印

// 顺序表打印
void SLPrint(SL s);

为了更好地对程序进行调试,我们这里需要写一个打印程序,以便我们测试每一个接口函数。

// 顺序表打印
void SLPrint(SL s)
{
	for (int i = 0; i < s.size; i++)
	{
		printf("%d ", s.arr[i]);
	}
	printf("\n");
}

附:我们完成这些前导工作,接下来我们就可以正式编写顺序表的功能函数。

2.5 顺序表尾插

// 顺序表尾插
void SLPushBack(SL* ps, SLDataType x);

我们得分两种情况:

不过在尾插元素之前,我们必须得确保数组空间大小是足够的,也就是说得有空间插入元素。如果说空间容量不够的话,我们就得扩容,所以说在尾插之前,我们得判断空间大小是否足够,不够咱就扩容。我们这里得写一个内存容量检查函数。

这里我们还得注意一个点:就是我们内存空间不够的情况下,一般我们是以2倍或者3倍  capacity(容量) * 2 * sizeof(数据类型) 去开辟空间。

// 检查内存函数
void SLCheckCapacity(SL* ps)
{
	// 插入数据之前看空间够不够
	if (ps->capacity == ps->size)
	{
		// 申请空间
		// 申请之前,要判断一下capacity是否为0
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;

		 错误写法:这里不要直接这样写,要不然申请空间失败的话,前面的数据会丢失
		//ps->arr = (SLDataType*)realloc(ps->arr, newCapacity * 2 * sizeof(SLDataType));

		// 正确写法
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * 2 * sizeof(SLDataType));

		// 如果申请失败
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);	// 直接退出程序,不再继续执行
		}
		// 空间申请成功
		ps->arr = tmp;
		ps->capacity = newCapacity;
	}
}

检查开辟完空间后,我们就可以进行下一步,顺序表尾插接口函数编写。

步骤:

① 程序开始前,我们要断言一下,确保指针是有效的,不是NULL;

② 检查内存是否足够;

③ 将我们需要的 x 尾插入下标 ps->size 的位置,插完之后,数组元素总个数 ps->size 得加1。

// 顺序表尾插
void SLPushBack(SL* ps, SLDataType x)
{
	 温柔的解决方式
	//if (ps == NULL)
	//	return;
	assert(ps); // 等价于assert(ps != NULL)

	// 检查内存
	SLCheckCapacity(ps);

	/*ps->arr[ps->size] = x;
	++ps->size;*/
	ps->arr[ps->size++] = x;
}

2.6 顺序表头插

// 顺序表头插
void SLPushFront(SL* ps, SLDataType x);

我们也得分两种情况:

不过我们在头插元素之前,我们也得确保数组空间大小是足够的,所以我们头插之前也得调用一下内存检查函数 SLCheckCapacity,保证我们内存容量是足够的。

步骤:

① 程序开始前,我们要断言一下,确保指针是有效的,不是NULL;

② 检查内存是否足够;

③ 将我们需要的 x 头插入下标 0 的位置,插完之后,数组元素总个数 ps->size 得加1。

// 顺序表头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	// 检查内存
	SLCheckCapacity(ps);

	// 先让顺序表中已有的数据整体往后挪动一位
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1]; // arr[1] = arr[0]
	}
	ps->arr[0] = x;
	ps->size++;
}

2.6 顺序表尾删

// 顺序表尾删
void SLPopBack(SL* ps);

我们删除数据不是说要把这个数据从数组中去除,而是说我们这个所谓的“删除的数据”不能被访问,所以我们只需把数组中有效的元素个数 size - 1 即可,并不需要把这个数据变成什么其他的数,这是非常多余的(如果非要更改删除数据也不是不可)。

步骤:

① 程序开始前,我们要断言一下,确保指针是有效的,不是NULL;

② 断言一下,数据有效个数不能为0;

③ 将数据有效个数 size - 1。

// 顺序表尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);	// 顺序表有效数字不能为0
	// 顺序表不能为空
	//ps->arr[ps->size - 1] = -1;	// 这行代码有点多余
	ps->size--;
}

附:尾删还是非常简单的!

2.7 顺序表

// 顺序表头删
void SLPopFront(SL* ps);

头删数据之后,我们还需要每个数据往前一位,最后 size - 1。

步骤:

① 程序开始前,我们要断言一下,确保指针是有效的,不是NULL;

② 断言一下,数据有效个数不能为0;

③  然后将每个数据往前移动一位;

③ 将数据有效个数 size - 1。

// 顺序表头删
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);	// 顺序表有效数字不能为0

	// 数据整体往前挪动一位
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1]; // 最后一次,arr[size - 2] = arr[size - 1]
	}
	ps->size--;
}

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

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

相关文章

开源205W桌面充电器,140W+65W升降压PD3.1快充模块(2C+1A口),IP6557+IP6538

开源一个基于IP6557和IP6538芯片的205W升降压快充模块&#xff08;140W65W&#xff09;&#xff0c;其中一路C口支持PD3.1协议&#xff0c;最高输出28V5A&#xff0c;另一路是A口C口&#xff0c;最高输出65W&#xff08;20V3.25A&#xff09;&#xff0c;可搭配一个24V10A的开关…

Ubuntu20.04 安装 cudatookit 12.2 + cudnn 安装

最简约的部署Ubuntu20.04深度学习环境的教程 1. 安装Ubuntu20.04 系统 B站详细的安装教程 简约安装版 2. 安装Nvidia显卡驱动 我参考了各种资料&#xff0c;重装系统&#xff0c;完美解决开机显示器黑屏无法进入桌面的情况 黑屏问题主要是由linux内核更新导致&#xff0c;…

混合注意力机制 -- Convolutional Block Attention Module(CBAM)

CBAM CBAM 模块概述 通道注意力模块&#xff08;Channel Attention Mechanism&#xff09;和空间注意力模块&#xff08;Spatial Attention Mechanism&#xff09;是注意力机制的两种主要形式&#xff0c;它们分别通过对通道维度和空间维度的特征图进行加权&#xff0c;从而使…

算法金 | Transformer,一个神奇的算法模型!!

大侠幸会&#xff0c;在下全网同名「算法金」 0 基础转 AI 上岸&#xff0c;多个算法赛 Top 「日更万日&#xff0c;让更多人享受智能乐趣」 抱个拳&#xff0c;送个礼 在现代自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;Transformer 模型的出现带来了革命性的变…

每日一题-验证回文串

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” //验证回文串 #include<vector> class Solution { public:bool reverseString(char s) {return (s > a && s < z) ||(s > 0 && s < 9) ||(s…

Lesson 43 Hurry up!

Lesson 43 Hurry up! 词汇 of course 当然【口语】 经常出现在口语交际中&#xff1a; Of course not. 当然不。 同义词&#xff1a; Certainly 当然。 Certainly not. 当然不。 注意语气&#xff1a;略带挑衅。Sure. 当然。 Sure not. 当然不。 Not sure. 不一定。 kettle…

Pandas 学习笔记(一)

一、pandas简介 Pandas 是 Python 语言的一个扩展程序库&#xff0c;用于数据分析。 Pandas 名字衍生自术语 "panel data"&#xff08;面板数据&#xff09;和 "Python data analysis"&#xff08;Python 数据分析&#xff09;。 Pandas 是一个开放源码…

Python + OpenCV 酷游地址教学V鄋KWK3589

本篇文章汇整了一系列的Python OpenCV 教学&#xff0c;只要按照教学文的顺序阅读和实作&#xff0c;就可以轻松入门OpenCV&#xff0c;并透过OpenCV 实现许多影像相关的创意应用。 接下来我们来介绍OpenCV-- OpenCV 是一个跨平台的电脑视觉函式库( 模组) &#xff0c;可应用…

CesiumJS【Basic】- #042 绘制纹理线(Primitive方式)

文章目录 绘制纹理线(Primitive方式)1 目标2 代码2.1 main.ts3 资源文件绘制纹理线(Primitive方式) 1 目标 使用Primitive方式绘制纹理线 2 代码 2.1 main.ts var start = Cesium.Cartesian3

SSM泰华超市商品管理系统-计算机毕业设计源码11946

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据新增流程 3.2.2 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.5本章小结 3 系统总体设…

一键把二次元老婆拉进现实(Stable Diffusion进阶:ControlNet LineArt模型)

大家好我是极客菌&#xff01;&#xff01;&#xff01; 操作&#xff0c;就能将二次元老婆拉进现实&#xff0c;成为你的专属女友。本文将带你深入了解ControlNet LineArt模型的使用方法&#xff0c;助你轻松实现这一梦想。 ControlNet LineArt模型是Stable Diffusion的最新…

AI大模型日报#0701:Meta发布LLM Compiler、扒一扒Sora两带头人博士论文

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE-4.0-8K-latest&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xff01;《AI大模型日报》今日要点&#xf…

32.哀家要长脑子了!

1.299. 猜数字游戏 - 力扣&#xff08;LeetCode&#xff09; 公牛还是挺好数的&#xff0c;奶牛。。。妈呀&#xff0c;一朝打回解放前 抓本质抓本质&#xff0c;有多少位非公牛数可以通过重新排列转换公牛数字&#xff0c;意思就是&#xff0c;当这个数不是公牛数字时&#x…

控制器方法执行流程和 @InitBinder【Spring源码学习】

控制器方法执行流程 InitBinder 加在ControllerAdvice中 首先说明ControllerAdvice和aop没有任何关系&#xff01; 加在ControllerAdvice中只对所有控制器都生效 全局的在开始时就会保存到handlerMappingAdapter中的cache中&#xff1b; 加在Controller中 加在controller中只对…

TS---typescript的安装和tsc命令使用

什么是TS---typescript&#xff1f; &#xff08;TypeScript是Microsoft公司注册商标&#xff09; TypeScript具有类型系统&#xff0c;且是JavaScript的超集&#xff0c; 它可以编译成普通的JavaScript代码。TypeScript支持任意浏览器&#xff0c;任意环境&#xff0c;任意系…

仓库管理系统24--统计报表

原创不易&#xff0c;打字不易&#xff0c;截图不易&#xff0c;多多点赞&#xff0c;送人玫瑰&#xff0c;留有余香&#xff0c;财务自由明日实现 1、引用LiveCharts 2、创建LiveChartViewModel using GalaSoft.MvvmLight; using LiveCharts.Wpf; using LiveCharts; using Sy…

手把手搞定报名亚马逊科技认证

引言 亚马逊云科技认证考试为我们这些技术从业者提供了提升专业技能的机会。无论选择线上还是线下考试&#xff0c;每种方式都有其独特的优势和挑战。选择合适的考试方式将帮助我们更好地展示自己的技术水平。以下是我对不同考试方式的优缺点介绍&#xff0c;以及各科目的考试…

Java案例抢红包

目录 一&#xff1a;题目要求&#xff1a; 二&#xff1a;思路分析&#xff1a;&#xff08;遇见问题先想出完整的思路逻辑再去动手事半功倍&#xff09; 三&#xff1a;具体代码&#xff1a; 一&#xff1a;题目要求&#xff1a; 二&#xff1a;思路分析&#xff1a;&#x…

基于隐马尔可夫模型的股票预测【HMM】

基于机器学习方法的股票预测系列文章目录 一、基于强化学习DQN的股票预测【股票交易】 二、基于CNN的股票预测方法【卷积神经网络】 三、基于隐马尔可夫模型的股票预测【HMM】 文章目录 基于机器学习方法的股票预测系列文章目录一、HMM模型简介&#xff08;1&#xff09;前向后…

Python容器 之 列表--下标和切片

列表的切片 得到是 新的列表字符串的切片 得到是 新的字符串 如果下标 不存在会报错 list1 [1, 3.14, "hello", False] print(list1)# 获取 列表中 第一个数据 print(list1[0]) # 1# 获取列表中的最后一个数据 print(list1[-1]) # [False]# 获取中间两个数 即 3.1…