数据结构——lesson2线性表和顺序表

目录

前言

 一、顺序表是什么?

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

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

二、接口实现

1.动态顺序表存储

2.基本增删查改接口

(1)初始化顺序表

(2)顺序表摧毁

(3)检查空间

(4)顺序表打印

(5)顺序表尾插

(6)顺序表尾删

(7)顺序表头插

(8)顺序表头删

(9)顺序表在pos位置插入x

(10)顺序表在pos位置删除x

(11)顺序表查找

3.代码运行结果如下:



前言

在学习顺序表之前我们要了解什么是线性表?

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

 一、顺序表是什么?


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

顺序表一般可以分为:

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

//顺序表的静态存储
#define N 7
typedef int SLDataType;//防止数组类型改变时麻烦

typedef struct SeqList
{
 SLDataType arry[N];//定长数组
 size_t size;//有效数据个数

}SeqList;

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

//顺序表的动态存储
typedef struct SeqList
{
	SLDataType* arry;//指向动态开辟的数组
	size_t size;//有效数据个数
	size_t capacity;//容量空间的大小
}SeqList;//空间不够则增容
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致 N 定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用 动态顺序表 ,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

二、接口实现

1.动态顺序表存储

:相较于静态顺序表动态顺序表arry表示的指针数据,不再是定长数组,从而可以使用mallo,realloc函数开辟动态内存空间,此外还增加了capacity变量来记录容量大小

typedef struct SeqList
{
	SLDataType* arry;//指向动态开辟的数组
	size_t size;//有效数据个数
	size_t capacity;//容量空间的大小
}SeqList;//空间不够则增容

①SLDataType:其实是int被typedef的

typedef int SLDataType;//防止数组类型改变时麻烦

②size_t:无符号位的整型

2.基本增删查改接口

(1)初始化顺序表

:(1)asert断言防止传入指针为空;

       (2)使用malloc函数给数组开4个SLDataType(typedef为int,避免修改数据的麻烦)大小的空间;

void SeqListInit(SeqList* psl)//顺序表初始化
{
	assert(psl);//asert断言防止传入指针为空
	psl->arry = (SLDataType*)malloc(sizeof(SLDataType) * 4);//给数组开4个SLDataType大小的空间
	if (psl == NULL)
	{
		perror("malloc fail");//如果开辟没成功则返回错误
		return;
	}
	psl->size = 0;
	psl->capacity = 4;
}

(2)顺序表摧毁

:使用动态内存函数(malloc、realloc等函数)后记得要用free释放空间;

void SeqListDestory(SeqList* psl)//顺序表销毁
{
	assert(psl);//assert断言
	free(psl->arry);//使用动态内存函数后记得要用free释放空间
	psl->arry = NULL;//指针置空
	psl->capacity = 0;
	psl->size = 0;
}

(3)检查空间

:①如果空间满了使用realloc函数来增加空间;

        ②需要人为的将capacity增加到相应的容量(只是内存容量增加了,我们要将capacity与内存链接需要自己动手);

void CheckCapacity(SeqList* psl)
{
	assert(psl);//断言
	if (psl->size == psl->capacity)//判断空间是否满了
	{
		SLDataType* tmp = realloc(psl->arry, sizeof(SLDataType) * 2 * (psl->capacity));
        //增容每次扩展为上一次的2倍
		if (tmp == NULL)//判断是否开辟成功
		{
			perror("realloc fail");
			return;
		}
		psl->arry = tmp;
		psl->capacity *= 2;//开辟成功指示容量的capacity要相应的增加
	}
}

(4)顺序表打印

for循环逐一打印即可;

void SeqListPrint(SeqList* psl)
{
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
		printf("%d ", psl->arry[i]);
	}
	printf("\n");
}

(5)顺序表尾插

:①尾插数据也是增加数据所以要用检查容量函数(CheckCapacity)检查容量;

        ②相应元素加进去后,顺序表指向有效数据个数(size)要增加(类似于增加容量时capacity也要增加);

        ③后续等学习了在特定位置(pos)插入相应元素后即可使用SeqListInsert函数,能大大提高代码的利用率,此时应该在顺序表的尾端也就是下标为size的地方插入x;

void SeqListPushBack(SeqList* psl, SLDataType x)
{
	assert(psl);//断言
	CheckCapacity(psl);//检查容量
	psl->arry[psl->size] = x;
	psl->size++;//顺序表个数要相应增加
	//SeqListInsert(psl,ps->size,x);//在特定位置插入元素x
}

(6)顺序表尾删

:①要先判断顺序表中是否储存了元素,如果没有则没有继续的必要;

        ②因为顺序表是通过数组下标访问,所以只要将最大的下标减一即可,这样就访问不到最后的元素了,可以看成删掉了一个元素;

        ③后续等学习了在特定位置(pos)删除相应元素后即可使用SeqListErase函数,能大大提高代码的利用率,此时应该在顺序表的尾端也就是下标为size-1的地方删除;

void SeqListPopBack(SeqList* psl)
{
	assert(psl);//断言
	if (psl->size == 0)//判断顺序表是否有元素
	{
		return;//没有直接返回
	}
	psl->size--;//顺序表个数-1
	//SeqListErase(ps,ps->size-1);//在顺序表末尾删除元素
}

(7)顺序表头插

:①头插数据也是增加数据所以要用检查容量函数(CheckCapacity)检查容量;

        ②头插数据之前的数据下标要整体+1;顺序表个数也要+1;

        ③后续等学习了在特定位置(pos)插入相应元素后即可使用SeqListErase函数,能大大提高代码的利用率,此时应该在顺序表的首端也就是下标为0的地方插入x;

void SeqListPushFront(SeqList* psl, SLDataType x)//顺序表头插
{
	assert(psl);
	CheckCapacity(psl);//检查容量
	
	for (int i = psl->size-1; i >= 0; i--)//顺序表整体向后移
	{
		psl->arry[i + 1] = psl->arry[i];
	}
	psl->size++; //顺序表个数+1
	psl->arry[0] = x;
	//SeqListInsert(ps,0,x);//在下标为0的位置插入x
}

(8)顺序表头删

:①要先判断顺序表中是否储存了元素,如果没有则没有继续的必要;

        ②删除第一个元素,顺序表下标都要-1;

        ③顺序表元素个数(size)也要-1;

        ④后续等学习了在特定位置(pos)删除相应元素后即可使用SeqListErase函数,能大大提高代码的利用率,此时应该在顺序表的尾端也就是下标为0的地方删除;

void SeqListPopFront(SeqList* psl)//顺序表头删
{
	assert(psl);//断言
	if (psl->size == 0)//判断是否为空
		return;
	for (int i = 1; i < psl->size; i++)//顺序表数据整体都要前移
	{
		psl->arry[i - 1] = psl->arry[i];
	}
	psl->size--;//顺序表个数-1
	//SeqListErase(ps,0);//在下标为0位置删除
}

(9)顺序表在pos位置插入x

:①在特定位置插入数据也是增加数据所以要用检查容量函数(CheckCapacity)检查容量;

        ②判断插入下标pos是否合理(要小于size);

        ③插入pos位置的数据,其后的数据下标都要整体+1;

        ④顺序表元素个数(size)要+1;

void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)//在pos位置插入x
{
	assert(psl);//断言
	assert(pos <= psl->size);//判断pos是否小于最大的下标
	CheckCapacity(psl);//检查容量
	for (int i = psl->size - 1; i >= pos; i--)//下标在pos之后的要整体+1
	{
		psl->arry[i + 1] = psl->arry[i];
	}
	psl->arry[pos] = x;//将x插入pos位置
	psl->size++;//顺序表元素个数+1
}

(10)顺序表在pos位置删除x

:①删除元素size要-1;

        ②在pos位置删除元素,pos之后的下标都要-1;

void SeqListErase(SeqList* psl, size_t pos)//在特定位置删除元素
{
	assert(psl);//断言
	for (int i = pos + 1; i < psl->size; i++)//pos之后下标-1
	{
		psl->arry[i - 1] = psl->arry[i];
	}
	psl->size--;//顺序表元素个数-1;
}

(11)顺序表查找

int SeqListFind(SeqList* psl, SLDataType x)//顺序表查找
{
	assert(psl);//断言
	if (psl->size == 0)//判断是否为空
		return -1;
	for (int i = 0; i < psl->size; i++)//循环逐一查找
	{
		if (psl->arry[i] == x)
		{
			printf("%d\n", i);
			return i;//找到了返回下标
		}
	}
	printf("没找到\n");
    return -1
}

3.代码运行结果如下:

以上就是顺序表的所以内容啦,欢迎三连回访,有问题可以后台私信我或者打在评论区哦~ 

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

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

相关文章

Elasticsearch:倒数排序融合 - Reciprocal rank fusion (RRF)

注意&#xff1a;RRF 在 Elastic Stack 8.8 中正式提供。 倒数排序融合&#xff08;RRF&#xff09;是一种将具有不同相关性指标的多个结果集组合成单个结果集的方法。 RRF 无需调优&#xff0c;不同的相关性指标也不必相互关联即可获得高质量的结果。该方法的优势在于不利用相…

VBA技术资料MF118:在多个工作表中插入页眉和页脚

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。我的教程一共九套&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到…

如何在PDF 文件中删除页面?

查看不同的工具以及解释如何在 Windows、Android、macOS 和 iOS 上从 PDF 删除页面的步骤&#xff1a; PDF 是最难处理的文件格式之一。曾经有一段时间&#xff0c;除了阅读之外&#xff0c;无法用 PDF 做任何事情。但是今天&#xff0c;有许多应用程序和工具可以让您用它们做…

片上网络NoC(3)——拓扑指标

目录 一、概述 二、指标 2.1 与网络流量无关的指标 2.1.1 度&#xff08;degree&#xff09; 2.1.2 对分带宽&#xff08;bisection bandwidth&#xff09; 2.1.3 网络直径&#xff08;diameter&#xff09; 2.2 与网络流量相关的指标 2.2.1 跳数&#xff08;hop coun…

【复现】Supabase后端服务 SQL注入漏洞_48

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 Supabase是什么 Supabase将自己定位为Firebase的开源替代品&#xff0c;提供了一套工具来帮助开发者构建web或移动应用程序。 Sup…

LeetCode、208. 实现 Trie (前缀树)【中等,自定义数据结构】

文章目录 前言LeetCode、208. 实现 Trie (前缀树)【中等&#xff0c;自定义数据结构】题目链接与分类思路 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术领…

车载诊断协议DoIP系列 —— OSI模型DoIP参考

车载诊断协议DoIP系列 —— OSI模型DoIP参考 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,喝完再…

Vue源码系列讲解——模板编译篇【三】(HTML解析器)

目录 1. 前言 2. HTML解析器内部运行流程 3. 如何解析不同的内容 3.1 解析HTML注释 3.2 解析条件注释 3.3 解析DOCTYPE 3.4 解析开始标签 3.5 解析结束标签 3.6 解析文本 4. 如何保证AST节点层级关系 5. 回归源码 5.1 HTML解析器源码 5.2 parseEndTag函数源码 6. …

使用MICE进行缺失值的填充处理

在我们进行机器学习时&#xff0c;处理缺失数据是非常重要的&#xff0c;因为缺失数据可能会导致分析结果不准确&#xff0c;严重时甚至可能产生偏差。处理缺失数据是保证数据分析准确性和可靠性的重要步骤&#xff0c;有助于确保分析结果的可信度和可解释性。 在本文中&#…

Linux_环境变量_命令行参数

一.环境变量 在Linux中自己写的程序必须要带路径才能运行&#xff0c;相对路径或是绝对路径&#xff0c;但是像ls pwd这样的程序&#xff0c;不带路径也能运行。当你想要运行一个程序时&#xff1a; 如果带有路径的话&#xff0c;则直接将对应路径的程序加载进内存&#xff0…

LeetCode、1268. 搜索推荐系统【中等,前缀树+优先队列、排序+前缀匹配】

文章目录 前言LeetCode、1268. 搜索推荐系统【中等&#xff0c;前缀树优先队列、排序前缀匹配】题目类型及分类思路API调用&#xff08;排序前缀匹配&#xff09;前缀树优先队列 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创…

内网穿透 | 推荐两个免费的内网穿透工具

目录 1、简介 2、Ngrok 2.1、下载安装 2.2、运行 2.3、固定域名 2.4、配置多服务 3、cpolar 3.1、下载安装 3.2、运行 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应…

2024 年 5 款适用于免费 iPhone 数据恢复的工具软件

搜索一下&#xff0c;你会发现许多付费或免费的iPhone数据恢复工具声称它们可以帮助你以很高的成功率找回所有丢失的数据。然而&#xff0c;这正是问题所在。真的很难做出选择。为了进一步帮助您解决数据丢失问题&#xff0c;我们在此列出了 5 款最好的免费 iPhone 恢复软件供您…

[Doris] Doris的安装和部署 (二)

文章目录 1.安装要求1.1 Linux操作系统要求1.2 软件需求1.3 注意事项1.4 内部端口 2.集群部署2.1 操作系统安装要求2.2 下载安装包2.3 解压2.4 配置FE2.5 配置BE2.6 添加BE2.7 FE 扩容和缩容2.8 Doris 集群群起脚本 3.图形化 1.安装要求 1.1 Linux操作系统要求 1.2 软件需求 1…

Hive的小文件问题

目录 一、小文件产生的原因 二、小文件的危害 三、小文件的解决方案 3.1 小文件的预防 3.1.1 减少Map数量 3.1.2 减少Reduce的数量 3.2 已存在的小文件合并 3.2.1 方式一&#xff1a;insert overwrite (推荐) 3.2.2 方式二&#xff1a;concatenate 3.2.3 方式三&#xff…

[Python] 如何用import导入模块

本篇博客来记以下关于import导入模块的笔记~ 可莉将这篇博客收录在了&#xff1a;《Python》 可莉推荐的优质博主主页&#xff1a;Kevin ’ s blog 我们在Python中可以使用import从标准库中导入一天模块&#xff0c;模块相当于是一个 .py 文件&#xff0c;我们导入后调用相当于…

腾讯云4核8G服务器多少钱?646元一年零3个月

腾讯云服务器4核8G配置优惠价格表&#xff0c;轻量应用服务器和CVM云服务器均有活动&#xff0c;云服务器CVM标准型S5实例4核8G配置价格15个月1437.3元&#xff0c;5年6490.44元&#xff0c;轻量应用服务器4核8G12M带宽一年446元、529元15个月&#xff0c;腾讯云百科txybk.com分…

pythondjangomysql苏州一日游之可视化分析69216-计算机毕业设计项目选题推荐(附源码)

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对旅游服务等问题&#xff0c;对旅游服务进行…

【动态规划】【中位数】【C++算法】1478. 安排邮筒

# 作者推荐 【深度优先搜索】【树】【图论】2973. 树中每个节点放置的金币数目 本文涉及知识点 动态规划汇总 LeetCode1478. 安排邮筒 给你一个房屋数组houses 和一个整数 k &#xff0c;其中 houses[i] 是第 i 栋房子在一条街上的位置&#xff0c;现需要在这条街上安排 k…

C++基础入门:掌握核心概念(超全!)

C作为一门广泛使用的编程语言&#xff0c;以其高性能和灵活性在软件开发领域占据重要地位。无论是游戏开发、系统编程还是实时应用&#xff0c;C都是一个不可或缺的工具。本博客旨在为初学者提供C编程语言的核心概念&#xff0c;帮助你建立坚实的基础。 C关键字 C关键字是编程…