数据结构——顺序表

即使你内心没有一尊明月,也要给自己留下一方皎洁 

文章目录

什么是顺序表

顺序表的实现

顺序表内部基础设置

结构体数据类型重定义

顺序表结构定义

顺序表空间初始化及扩容设置

顺序表空间的初始化及销毁

顺序表的扩容 

顺序表基本功能

尾插尾删

头插头删

在任意位置删和插 


  大家好,我是纪宁。

  本文将介绍顺序表的内容,此内容为数据结构的入门内容,可以为后面的链表等困难数据结构的学习做铺垫。希望大家和我都可以将数据结构的基础扎实!

  有需要的老铁可以去看博主的往期作品 数据结构与算法对程序员的重要性icon-default.png?t=N6B9http://t.csdn.cn/muEFA

  本文使用的顺序表类型名和函数名如下表

SeqList顺序表
SLDataType重定义顺序表成员数据类型
SLInit初始化顺序表
SLDestroy销毁顺序表
SLPrint打印顺序表
SLCheckCapacity检查顺序表容量
SLPushFront头插
SLPopFront

头删

SLPushBack尾插
SLPopBack尾删
SLInsert在pos位置插入
SLErase删除pos位置的成员

什么是顺序表

  顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,通俗的来讲就是数组存储,在数组的基础上多了增删查改的功能。

  一般顺序表分为静态顺序表和动态顺序表。静态顺序表采用定长数组存储元素的形式,动态顺序表使用动态开辟的数组存储。因为顺序表只适用于已知需要存储多少数据的形式,而到底数组长度  N 空间开辟多大难以把握(开辟太大导致空间浪费,太少导致不够用)。所以我们一般使用的是动态顺序表,可以动态分配内存大小。

顺序表的实现

顺序表内部基础设置

  顺序表的基础设置中包括顺序表结构体的定义和结构体数据类型的重定义,结构开辟的动态数组空间是由 SLDataType*(重定义)类型的指向顺序表成员的指针表示顺序表最大空间的变量 capacity 共同维护的。

结构体数据类型重定义

typedef int	SLDataType;

  将顺序表内的数据类型重定义,可以方便顺序表成员数据类型的修改。如果要修改结构体变量数据类型(如由 int 变为 double)时,只需要修改 typedef 后面的数据类型,那么程序中顺序表的元素类型变为 double 型。

顺序表结构定义

typedef struct SeqList
{
	SLDataType* arr;
	int sz; 
	int capacity; 
}SL;

  arr是一个指针,指向动态开辟的顺序表数组,数据类型为 typedef 重定义后的数据类型,方便修改;sz表示顺序表元素个数capacity表示顺序表的最大空间

顺序表空间初始化及扩容设置

顺序表空间的初始化及销毁

void SLInit(SL* s)
{
	s->arr = (SLDataType*)malloc(4 * sizeof(SLDataType));
	if (s->arr == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	s->sz = 0;
	s->capacity = 4;
}

  首先,可以使用 malloc 函数开辟 k 个成员的空间,并且将首空间的地址强转后赋值给 arr 指针,同时将最大空间变量 capacity 赋值为4,但顺序表成员个数变量 sz 依旧是0,因为只是初始化了顺序表空间,并未往顺序表中加入成员。

  在程序结束的阶段,在保存数据后,最好做到能将顺序表销毁。

void SLDestroy(SL* s)
{
	free(s->arr);
	s->arr = NULL;
	s->sz = s->capacity = 0;
}

  销毁阶段将初始化时开辟的内存释放,并将指针置空,同时成员个数 sz 和 最大空间 capacity 的值都改为0。

顺序表的扩容 

  因为动态的顺序表初始状态下只开辟了较少的空间,在程序判断出顺序表内存空间已满后要进行顺序表空间的扩容处理,所以最好可以封装一个函数,达到既可以判断最大空间与当前成员的关系(即判断满没满),又能在将顺序表扩容。

void SLCheckCapacity(SL* s)
{
	if (s->sz == s->capacity)
	{
		SLDataType* tmp = realloc(s->arr, 2 * sizeof(SLDataType) * (s->capacity));
		if (tmp == NULL)
		{
			perror("realloc");
			exit(-1);
		}
		else
		{
			s->arr = tmp;
			s->capacity *= 2;
		}
	}
}

  使用 realloc  函数可以将顺序表扩容,因为 realloc 每扩容一次都需要耗费一定的资源,那么如果使用过于频繁,势必会让内存的压力变得非常大,所以一般顺序表扩容都是以2倍的速度增长。realloc 函数扩容动态内存分为原地扩容和异地扩容,可以先用一个指针来接受扩容后的首地址,再赋值给 arr,同时顺序表的最大空间乘2。

顺序表基本功能

  顺序表的基本功能为头插、头删、尾插、尾删

尾插尾删

void SLPushBack(SL* s, SLDataType x)
{
	SLCheckCapacity(s);
	*(s->arr + s->sz) = x;
	s->sz++;
}
void SLPpoBack(SL* s)
{
	if (s->sz == 0)
	{
		exit(-1);
	}
	s->sz--;
}

  顺序表尾插之前要检查顺序表是否需要增容,然后将元素插在 arr[sz] 的位置即可,尾删的时候需要注意如果元素个数为0,就要强制要退出或断言

头插头删

void SLPushFront(SL* s, SLDataType x) 
{
	SLCheckCapacity(s);
	if (s->sz == 0)
	{
		s->arr[0] = x;
		s->sz++;
	}
	else
	{
		int i = 0;
		for (i = s->sz-1; i>=0; i--)
		{
			*(s->arr + i+1) = *(s->arr + i);
		}
		*(s->arr) = x;
		s->sz++;
	}
}
void SLPopFront(SL* s)
{
	if (s->sz == 0)
		exit(-1);
	else
	{
		int i = 0;
		for (i = 0; i < s->sz - 1; i++)
		{
			s->arr[i] = s->arr[i + 1];
		}
		s->sz--;
	}
}

  头插的时候要判断元素个数,如果没有成员,就直接将首元素赋值为 x ;如果有成员,就先将所有成员后移,再首元素赋值为 x,最后将元素个数 sz 加1。

  头删的时候只需要将所有成员前移一个位置,再将元素个数 sz 减1。

在任意位置删和插 

void SLInsert(SL* s, int pos, SLDataType x)
{
	s->sz++;
	int i = 0;
	for (i =s->sz-1-1; i>=pos; i--)
	{
		*(s->arr + i + 1) = *(s->arr + i);
	}
	*(s->arr + pos) = x;
}

void SLErase(SL* s, int pos)
{
	if (s->sz < pos)
		exit(-1);
	for (int i = pos; i < s->sz - 1; i++)
	{
		*(s->arr + i) = *(s->arr + i + 1);
	}
	s->sz--;
}

  在任意位置插入数据和删除数据其实原理和头插头删是一样的,在任意位置插和删只需要把握部分整体后移的‘度’就行,建议新手多画图来理解这种较为复杂的情况,尽量不要出现“代码5分钟,调试两小时。”的情况。

在这里插入图片描述

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

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

相关文章

css设置八等分圆

现需要上图样式的布局&#xff0c;我通过两张向右方的图片&#xff0c;通过定位和旋转完成了布局。 问题&#xff1a; 由于是通过旋转获取到的样式&#xff0c;实际的盒子是一个长方形&#xff0c;当鼠标移入对应的箭头时选中的可能是其他盒子&#xff0c;如第一张设计稿可以看…

10.函数

10.1为什么需要函数 ●函数: function&#xff0c;是被设计为 执行特定任务的代码块 ●作用&#xff1a; 精简代码方便复用&#xff08;实现代码复用&#xff0c;提高开发效率&#xff09; 比如我们前面使用的alert()、prompt() 和console.log()都是一些js函数&#xff0c;只不…

编译/反编译

1.Android APK 1.软件 1.apktool 1.作用&#xff1a;反编译apk或重新打包apk 2.dex2jar 1.作用&#xff1a;将Android的可执行文件.dex转换为.jar 3.jd-gui 1.作用&#xff1a;方便阅读jar文件的代码工具 2.步骤 1.通过apktool将apk软件反编译2.使用dex2jar将classes.dex文件转…

(十五) InfluxDB服务进程参数(influxd命令的用法)

以下内容来自 尚硅谷&#xff0c;写这一系列的文章&#xff0c;主要是为了方便后续自己的查看&#xff0c;不用带着个PDF找来找去的&#xff0c;太麻烦&#xff01; 第 15 章 InfluxDB服务进程参数&#xff08;influxd命令的用法&#xff09; 15.1 influxd命令罗列 1、我们的…

Django 图书管理系统

一、功能及页面设计 二、页面展示 (1)首页 (2)注册 (3)登录 (4)普通用户登录 4.1查看图书页面 4.2查看图书详情页 4.3修改密码 (5)管理员登录 5.1添加图书 5.2添加图片 三、代码展示 因为代码太多不好一个个展示 所以需要源码的小伙伴可以找我要代码 感谢三连支持&#xff0…

【C++】多态原理剖析,Visual Studio开发人员工具使用查看类结构cl /d1 reportSingleClassLayout

author&#xff1a;&Carlton tag&#xff1a;C topic&#xff1a;【C】多态原理剖析&#xff0c;Visual Studio开发人员工具使用查看类结构cl /d1 reportSingleClassLayout website:黑马程序员C tool&#xff1a;Visual Studio 2019 date&#xff1a;2023年7月24日 目…

最快桌面UI:Siticone Desktop UI 2.1.1 cRACK

富图尔主义控制 80 多个 .NET UI 组件和控件 现代未来 UI/UX 组件 为 Visual Studio 开发做好准备 无限的免费产品支持案例 超轻量和快速性能 广泛可定制和主题化 低资源消耗和占地面积 免版税开发和部署 NET 的最佳 UI 和 UX 库 从最好的图书馆探索无缝流畅的体验 使…

二、SQL-5.DQL-9.执行顺序

一、案例&#xff1a; 查询年龄大于15的员工的姓名、年龄&#xff0c;并根据年龄进行升序排序 select name, age from emp where age > 15 order by age asc; 先执行①from&#xff08;定义emp的别名为e&#xff09;&#xff0c;再执行②where&#xff08;调用别名e&…

SpringBoot集成Druid实现数据库连接池

一、引入依赖 完整的pom文件如下所示: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http…

如何从任何地方远程解决电脑问题?

​如何远程解决电脑问题&#xff1f; “嗨&#xff01;我有一台Windows 10家用电脑。我外出旅行&#xff0c;但我的家人告诉我我的电脑有一段时间无法正常工作。我该如何远程检查电脑并解决相应的问题&#xff1f;提前谢谢&#xff01;” 您是否正在寻找远程解决电…

JAVA解析EXCEL(JExcelAPI,POI,EasyExcel)

前言 文章目录 前言JExcelAPIDemo POIHSSFWorkBookXSSFWorkBookDemo SXSSFWorkBookDemo XSSFReaderDemo EasyExcelDemo demo代码&#xff1a;https://github.com/RwTo/excel-demo JAVA解析Excel 一般有三种方式 JExcelAPI POI EasyExcel JExcelAPI 官网&#xff1a;https://je…

【问题记录】Ubuntu 22.04 环境下,程序报:段错误(核心已转储)怎么使用 core 文件和GDB调试器 解决?

目录 环境 问题情况 解决思路 原因分析 解决方法 番外知识 环境 VMware Workstation 16 Pro &#xff08;版本&#xff1a;16.1.2 build-17966106&#xff09;ubuntu-22.04.2-desktop-amd64 问题情况 本人在运行百万并发的服务端程序时&#xff0c;程序运行报&#xff1a…

【云原生】Docker镜像的创建,Dockerfile

一、Docker镜像的创建 创建镜像有三种方法&#xff0c;分别为【基于已有镜像创建】、【基于本地模板创建】以及【基于Dockerfile创建】。 1.基于现有镜像创建 &#xff08;1&#xff09;首先启动一个镜像&#xff0c;在容器里做修改docker run -it --name web centos:7 /bin/…

UDS之27服务

SecurityAccess&#xff08;0x27&#xff09;—— 安全访问 这个服务的目的是为那些限制访问&#xff0c;以及和排放、安全相关的一些服务和数据提供一些访问权限来保护数据。 此服务执行步骤如下&#xff1a; &#xff08;1&#xff09;Client请求一个种子&#xff08;Seed…

可证明安全初步(Provable Security Basics)

Speecher: Bingsheng Zhang 这一系列的课程&#xff0c;为了介绍一些基础&#xff0c;弥补一些上密码学课和看论文的Gap。 历史上的密码学是art&#xff0c;就像鲁班锁&#xff0c;看着很精妙&#xff0c;但是没有证明。 1970s以来&#xff0c;逐渐发展成Science。 定义和模…

Vue3 axios数据请求封装

Vue3 axios数据请求封装 环境&#xff1a;vue3tsvite 首先在项目目录下安装axios 运行 npm install axios 成功后在package.json文件会显示。 目录&#xff1a; request.ts文件代码&#xff1a; import axios from axiosconst request axios.create({baseURL:https://api.…

20230721 Essex UK, Dongbing Gu 公开讲座--机器人前沿

个人主页&#xff1a; https://www.essex.ac.uk/people/GUDON81301/dongbing-gu 机器人领域任务的特点&#xff1a;dull, dirty, dangerous tasks in remote spaces 机器鱼&#xff1a; 实时港口环境监测 机器鱼群探索算法 化学传感器 水面声呐定位系统/SLAM/通信问题 Robotic …

SpringBoot中使用测试框架MockMvc来模拟HTTP请求测试Controller接口

场景 Java中进行单元测试junit.Assert断言、Mockito模拟对象、verify验证模拟结果、Java8中lambda的peek方法使用&#xff1a; Java中进行单元测试junit.Assert断言、Mockito模拟对象、verify验证模拟结果、Java8中lambda的peek方法使用_assert java8_霸道流氓气质的博客-CSD…

【MySQL】centos 7下MySQL的环境搭建

从本期博客开始我们正式进入到数据库的学习&#xff0c;在学习数据库时所用到的工具是Linux环境下的MySQL 目录 一、检查环境中是否装有MySQL 二、获取MySQL官方yum源 三、配置MySQL官方yum源 四、一键安装MySQL 五、启动mysql服务 六、登录MySQL 七、修改mysql配置文件…