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

news2025/6/29 23:02:23

目录

前言

 一、顺序表是什么?

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.代码运行结果如下:

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

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

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

相关文章

【JVM篇】什么是jvm

文章目录 &#x1f354;什么是Java虚拟机&#x1f6f8;Java虚拟机有什么用&#x1f339;Java虚拟机的功能&#x1f388;Java虚拟机的组成 &#x1f354;什么是Java虚拟机 JVM指的是Java虚拟机&#xff0c;本质上是一个运行在计算机上的程序&#xff0c;可以运行 Java字节码文件…

pytorch花式索引提取topk的张量

文章目录 pytorch花式索引提取topk的张量问题设定代码实现索引方法gather方法验证 补充知识expand方法gather方法randint pytorch花式索引提取topk的张量 问题设定 或者说&#xff0c;有一个(bs, dim, L)的大张量&#xff0c;索引的index形状为(bs, X)&#xff0c;想得到一个(…

位运算+leetcode ( 2 )

题一&#xff1a;只出现一次的数字&#xff08;1&#xff09; 1.链接 136. 只出现一次的数字 - 力扣&#xff08;LeetCode&#xff09; 2.思想 借用位运算中异或操作符的特点&#xff0c;a^a0&#xff0c;0^aa先定义一个sum0就用一个循环来遍历这个数组&#xff0c;每次都进行…

lv15 平台总线框架及案例 2

一、总线、设备、驱动 硬编码式的驱动开发带来的问题&#xff1a; 垃圾代码太多 结构不清晰 一些统一设备功能难以支持 开发效率低下 1.1 初期解决思路&#xff1a;设备和驱动分离 struct device来表示一个具体设备&#xff0c;主要提供具体设备相关的资源&#xff08;如…

小游戏和GUI编程(7) | SimpleNN 界面源码解析

小游戏和GUI编程(7) | SimpleNN 界面源码解析 0. 简介 SimpleNN 是 AdamYuan 在高中一年级时用 1 天时间写出来的简易 CNN, 使用 SFML 做 UI, 用于交互式输入手写数字&#xff0c;这个数字被训练好的 CNN 网络执行推理得到识别结果, 它的运行效果如下&#xff1a; 这一篇我们…

C语言——oj刷题——调整数组使奇数全部都位于偶数前面

题目&#xff1a; 输入一个整数数组&#xff0c;实现一个函数&#xff0c;来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分&#xff0c;所有偶数位于数组的后半部分。 一、实现方法&#xff1a; 当我们需要对一个整数数组进行调整&#xff0c;使得奇数位于数…

Solidworks:挑战新问题,不知道如何画出斜视图?

如果图形都是基于XYZ三个方向构造&#xff0c;没什么难度。如果有其他倾斜方向的&#xff0c;问题就难了。今天试了一下&#xff0c;看看我的3D模型。 出图纸的时候&#xff0c;不知道如何才能投影出斜视图&#xff0c;一边准确描述下面的那个小局部孔位。 补充&#xff1a;查了…

C++ Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统(3) 保存表格数据

对上两篇篇的工作C Qt框架开发| 基于Qt框架开发实时成绩显示排序系统&#xff08;1&#xff09;-CSDN博客和C Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统&#xff08;2&#xff09;折线图显示-CSDN博客继续优化&#xff0c;增加一个保存按钮&#xff0c;用于保存成绩数据…

八、克服冲动(Overcoming Impulses)

6.Overcoming Impulses 六、克服冲动 The skill of focus basically boils down to a tension between two different forces: the desire to work and the desire to quit. 专注的技巧基本上可以归结为两种力量之间的张力&#xff1a;工作的欲望和停止工作的欲望。 What makes…

猫头虎分享已解决Bug || Uncaught SyntaxError: Unexpected token

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

解锁未来:探秘Zxing二维码技术的神奇世界

解锁未来&#xff1a;探秘Zxing二维码技术的神奇世界 1. 引言 在当今数字化和智能化的社会中&#xff0c;二维码技术已经成为人们生活中不可或缺的一部分。从商品购物、支付结算到健康码、门票核销&#xff0c;二维码无处不在&#xff0c;极大地方便了人们的生活和工作。而Zx…

Vue3快速上手(三)Composition组合式API及setup用法

一、Vue2的API风格 Vue2的API风格是Options API,也叫配置式API。一个功能的数据&#xff0c;交互&#xff0c;计算&#xff0c;监听等都是分别配置在data, methods&#xff0c;computed, watch等模块里的。如下&#xff1a; <template><div class"person"…

[C++]17:二叉树进阶

二叉树进阶 一.二叉搜索树&#xff1a;1.二叉搜索树的概念&#xff1a;2.二叉搜索树的实现---循环版本&#xff1a;1.二叉搜索树的基本结构&#xff1a;2.查找&#xff1a;3.插入&#xff1a;4.中序遍历&#xff1a;5.删除&#xff1a; 3.二叉搜索树的实现---递归版本&#xff…

用代码视角揭秘刘谦扑克牌魔术

近日&#xff0c;刘谦回归春晚引发了热烈的讨论&#xff0c;尤其是刘谦表演的魔术《守岁共此时》中扑克牌登上了热搜。 如果要评选龙年春晚最好笑的节目&#xff0c;还得是尼格买提现场表演的翻车~ 除了台下的观众&#xff0c;相信很多电视机前的小伙伴也纷纷拿起扑克牌开始尝…

js中正则表达式的详解(应用场景)

文章目录 一、是什么二、匹配规则正则表达式标记贪婪模式懒惰模式分组 三、匹配方法str.match(regexp)str.matchAll(regexp)str.search(regexp)str.replace(regexp)str.split(regexp)regexp.exec(str)regexp.test(str) 四、应用场景参考文献 一、是什么 正则表达式是一种用来匹…

零售连锁门店管理软件有哪些好用?

在当今的零售行业中&#xff0c;随着连锁经营模式的普及和发展&#xff0c;对于高效、便捷的门店管理需求日益增加。一款好用的零售连锁门店管理软件&#xff0c;能够为商家提供全方位的解决方案&#xff0c;助力企业实现信息化管理&#xff0c;提升运营效率。那么&#xff0c;…

汉服租赁网站:Java技术的文化应用

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Xubuntu16.04系统中修改系统语言和系统时间

1.修改系统语言 问题&#xff1a;下图显示系统语言不对 查看系统中可用的所有区域设置的命令 locale -a修改/etc/default/locale文件 修改后如下&#xff1a; # File generated by update-locale LANG"en_US.UTF-8" LANGUAGE"en_US:en"LANG"en_US…

第三节课[LangChain]作业

文章目录 前言实践搭建向量知识库 前言 本次作业虽然是第三节课作业&#xff0c;但是在第四次作业之后才完成&#xff0c;所以用的是经过自我认知微调的小助手权重。 使用**诡秘之主和宿命之环小说&#xff08;仅用于学习和研究&#xff09;**以及设定集、百度百科&#xff0c…

智胜未来,新时代IT技术人风口攻略-第一版(弃稿)

文章目录 抛砖引玉 鸿蒙生态小科普焦虑之下 理想要落到实处校园鼎力 鸿蒙发展不可挡培训入场 机构急于吃红利企业布局 鸿蒙应用规划动智胜未来 技术人风口来临 鸿蒙已经成为行业的焦点&#xff0c;未来的发展潜力无限。作为一名程序员兼UP主&#xff0c;我非常荣幸地接受了邀请…