成为编程大佬!!----->数据结构与算法(2)——顺序表!!

前言:线性表是数据结构与算法的重中之重所有具有线性逻辑结构的数据结构,都能称为线性表。这篇文章我们先来讨论线性表中的顺序表,顺序表和线性表都是后续实现栈,树,串和图等等结构的重要基础。

目录

❀简单介绍线性表

❀顺序表

❀顺序表的存储

❀动态存储

❀静态存储

❀静态存储与动态存储的优缺点

❀顺序表操作

❀1.初始化顺序表

❀2.销毁顺序表

❀3.插入数据

❀插入数据之判断已满否

❀插入操作之尾插

❀插入操作之头插

❀插入数据之插入指定位置

❀4.删除数据

❀删除数据之尾删

❀删除数据之头删

❀删除数据之删除指定位置

❀5.查找顺序表单个数据

❀⭐6.打印顺序表中所有数据

❀结语


简单介绍线性表

对于某种数据结构的存储特点可以从两个方面来看:逻辑结构物理结构

逻辑结构由人想像出来的抽象结构

物理结构在内存上的存储结构

下面要介绍的顺序表——逻辑结构上,是一段依次排列的、连续存储的数据;在物理结构上,也是连续存储在内存上的。也就是说,顺序表在逻辑结构和物理结构上都是线性的而只要在逻辑结构上是线性的,它就是线性表)。

顺序表

因为顺序表在物理结构上是连续存储的,所以顺序表的本质就是数组。但是数据结构与算法需要对数据进行相关的管理(如增删查改),因此,我们需要对存储数据的数组进行封装。

顺序表的存储

我们用结构体来封装顺序表,结构体内除了包括存储数据的数组之外,我们再定义两个成员,用来保存顺序表的最大存储容量(capacity)顺序表的实际存储的有效数据(size)

动态存储

//顺序表中数据类型
typedef int SLdatatype;
//顺序表存储结构
typedef struct SeqList
{
	SLdatatype* arr;
	int capacity;
	int size;
}SL;

i.动态存储需要申请动态数组,通过调用动态内存管理函数来申请空间,然后通过指针arr保存申请空间的地址来形成动态数组。

ii.动态存储的顺序表,使用的是堆上的空间

静态存储

#define M 100

//顺序表中数据类型
typedef int SLdatatype;
//顺序表存储结构
typedef struct SeqList{
    SLdatatype arr[M];
    int capacity;
    int size;
}SL;

i.静态存储,只需直接创建数组即可。数组大小是定死的。

ii.静态存储的顺序表,使用的是栈上的空间

静态存储与动态存储的优缺点

然而在实际编码项目中,出现过量的空间浪费或者空间不足都有可能导致严重的问题。空间浪费会消耗不必要的存储成本; 空间不足,会导致数据的泄露或者丢失。这些情况都会对管理者和用户造成严重损失。

因此,我们优先使用申请空间自由度高的动态存储来实现顺序表(以下操作均以动态存储为基础来实现)。

顺序表操作

下方非重点操作打了星星。

1.初始化顺序表

//初始化
void SLInit(SL* ps)
{
	//全部置空置零
	ps->arr = NULL;
	ps->capacity = 0;
	ps->size = 0;
}

将顺序表的成员全部置空置零。

2.销毁顺序表

//销毁顺序表
void SLDestroy(SL* ps)
{
	if (!ps)
	{
		printf("empty ptr!\n");
		return;
	}
	free(ps->arr);//释放动态数组
	SLInit(ps);//初始化顺序表
}

i.首先要判断传入的顺序表指针是否为空。一来可以保证程序合理合法运行,二来也可以消除VS的警告(ps可能为空指针)

ii.释放动态数组

iii.初始化顺序表

3.插入数据

插入新的数据就会占用顺序表容量,因此我们要确保顺序表有充足的容量如果不够,我们得进行扩容

插入数据之判断已满否
void SLCheckSpace(SL* ps)
{
    if (!ps)
    {
        printf("empty ptr\n");
        return;
    }
    if (ps->capacity == ps->size)//空间已满
    {
        int newCapacity = 1;
        if (ps->capacity)
        {
            newCapacity = ps->capacity;
        }
        int* temp = (int*)realloc(ps->arr, sizeof(SLdatatype) * 2 * newCapacity);//扩容
        if (temp)//扩容成功
        {
            ps->arr = temp;//接收扩容后地址
            ps->capacity = 2 * newCapacity;//修改顺序表容量
        }
    }
    return;
}

i.首先要判断传入的顺序表指针是否为空一来可以保证程序合理合法运行,二来也可以消除VS的警告(ps可能为空指针)

ii.如果空间已满,我们就进行扩容。扩容方式将容量扩大到原来的两倍

iii.修改顺序表扩容后的容量ps->capcity。

!!注意!!如果顺序表刚进行初始化操作容量是零,此时容量乘2之后还是零

因此,我们要设置默认值newcapacity为1。当容量为0的时候,使newcapacity不变;当容量不为零时,使newcapacity等于原容量.

PS:为什么是要扩大到原来的两倍呢?

因为,如果我们在容量不够的时候,只扩容多一个数据单位的容量,那么在下次插入时,又要进行一次扩容。虽然没有空间浪费,但是次数繁多的扩容操作,会让程序的时间效率大大的降低。所以,我们采用这种扩容方式,这样就能大大减少扩容的次数(因为每次都使得顺序表的容量呈指数级增长),同时这样的操作所产生的浪费也是可以控制的。

再补充一点,我们也可以让顺序表的容量每次扩大到原来的3倍,4倍,5倍都可以,按照实际情况来选择即可。

插入操作之尾插
//尾插
void SLPushBack(SL* ps, SLdatatype x)
{
	if (!ps)//检查顺序表指针
	{
		printf("empty ptr!\n");
		return;
	}
	SLCheckSpace(ps);//检查扩容
	ps->arr[ps->size++] = x;//尾插后,size++
	return;
}

i.首先要判断传入的顺序表指针是否为空。一来可以保证程序合理合法运行,二来也可以消除VS的警告(ps可能为空指针)。

ii.进行检查扩容

iii.直接在顺序表最后的位置插入新数据(索引为ps->size)。

iiii.顺序表有效数据数ps->size++

插入操作之头插
//头插
void SLPushFront(SL* ps, SLdatatype x)
{
    if (!ps)
    {
        printf("empty ptr!\n");
        return;
    }
    SLCheckSpace(ps);
    int i = ps->size;
    while (i >= 1)
    {
        ps->arr[i] = ps->arr[i - 1];
        i--;
    }
    ps->arr[0] = x;
    ps->size++;
    return;
}

i.首先要判断传入的顺序表指针是否为空。一来可以保证程序合理合法运行,二来也可以消除VS的警告(ps可能为空指针)。

ii.检查扩容

iii.将所有的数据往后挪一个数据单位。从后面的数据开始依次往后挪,否则较后面的数据会被覆盖导致丢失。

iiii.将新数据插入顺序表第一个位置

iiiii.顺序表有效数据ps->size++

插入数据之插入指定位置
//插入指定位置数据
void SeqListInsert(SL* ps, SLdatatype x, int pos)
{
	if (!ps)
	{
		printf("empty ptr!\n");
		return;
	}
	if (pos < 0 || pos >= ps->size)
	{
		printf("wrong pos!\n");
		return;
	}
	SLCheckSpace(ps);
	for (int i = ps->size; i > pos; i--)//pos后数据往后挪1位
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;//插入数据
	ps->size++;//size加一
	return 0;
}

i.首先要判断传入的顺序表指针是否为空。一来可以保证程序合理合法运行,二来也可以消除VS的警告(ps可能为空指针)。

ii.判断插入位置pos是否合法

iii.检查扩容

iiii.将pos往后的数据都向后挪动一个数据单位。要从后面的数据开始依次往后挪,否则较后面的数据会被覆盖导致丢失。

iiiii.插入新数据到pos位置

iiiiii.顺序表有效数据容量ps->size++

4.删除数据

删除数据之尾删
//尾删
void SLPopBack(SL* ps, SLdatatype* x)
{
	if (!ps)
	{
		printf("empty ptr!\n");
		return;
	}
	if (ps->size == 0)
	{
		printf("无数据可删!\n");
		return;
	}
	*x = ps->arr[--ps->size];//x接收删除的数据
	//最终,size会被减1,删除的数据虽然仍保存在数组中,但不影响后续操作。
	return;
}

i.首先要判断传入的顺序表指针是否为空。一来可以保证程序合理合法运行,二来也可以消除VS的警告(ps可能为空指针)。

ii.判断顺序表是否还有数据可删除

iii.用x接收删除的数据

iiii.顺序表有效数据ps->size--

!!注意!!虽然顺序表中,实际上还存储着删除了的数据,但是这个数据由于ps->size的减小,已经无法访问或者使用,并且该残留数据也不会影响后续的操作。

删除数据之头删
//头删
void SLPopFront(SL* ps, SLdatatype* x)
{
	if (!ps)
	{
		printf("empty ptr!\n");
		return;
	}
	if (ps->size == 0)
	{
		printf("无数据可删!\n");
		return;
	}
	*x = ps->arr[0];//接收删除的数据
	int i = 1;
	while (i < ps->size)//数据整体往前挪
	{
		ps->arr[i - 1] = ps->arr[i];
		i++;
	}
	ps->size--;//size减1
	return;
}

i.首先要判断传入的顺序表指针是否为空。一来可以保证程序合理合法运行,二来也可以消除VS的警告(ps可能为空指针)。

ii.判断顺序表是否还有数据可删除

iii.用x接收删除的数据

iiii.将第一位往后的所有数据都往前挪一位,从而覆盖第一位数据。要从前面的数据开始依次往前挪,否则较前面的数据会被覆盖导致丢失。

iiii.顺序表有效数据数ps->size--

!!注意!!虽然顺序表经过该操作之后,ps->arr[size]上还保存着数据,但是这个数据由于ps->size的减小,已经无法访问或者使用,并且该残留数据也不会影响后续的操作。

删除数据之删除指定位置
//删除指定位置数据
void SeqListErase(SL* ps, int pos)
{
	if (!ps)
	{
		printf("empty ptr!\n");
		return;
	}
	if (pos < 0 || pos >= ps->size)
	{
		printf("wrong pos!\n");
		return;
	}
	if (ps->size == 0)
	{
		printf("无数据可删!\n");
		return;
	}
	for (int i = pos + 1; i < ps->size; i++)
	{
		ps->arr[i - 1] = ps->arr[i];
	}
	ps->size--;
	return;
}

i.首先要判断传入的顺序表指针是否为空。一来可以保证程序合理合法运行,二来也可以消除VS的警告(ps可能为空指针)。

ii.判断插入位置pos是否合法

iii.判断顺序表是否还有数据可删除

iiii.将pos往后的数据都向前挪动一个数据单位要从前面的数据开始依次往前挪,否则较前面的数据会被覆盖导致丢失。

iiiii.顺序表有效数据ps->size--

5.查找顺序表单个数据

//查找顺序表单个数据
int SeqListFind(SL* ps, SLdatatype x)
{
	if (!ps)
	{
		printf("empty ptr!\n");
		return -1;
	}
	if (ps->size == 0)
	{
		printf("顺序表为空!\n");
		return -1;
	}
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->arr[i] == x)
		{
			printf("数据x在顺序表的 %d 索引处\n", i);
			return i;
		}
	}
	printf("不存在这样的数据x\n");
	return -1;
}

i.首先要判断传入的顺序表指针是否为空。一来可以保证程序合理合法运行,二来也可以消除VS的警告(ps可能为空指针)。

ii.判断顺序表是否有数据。没有数据就没必要查找了。

iii.循环遍历顺序表来查找。找到了就返回其索引;没找到就打印数据不存在的信息,返回-1。

⭐6.打印顺序表中所有数据

(实际打印方式不只下方代码一种,可根据实际情况设计打印操作)

//输出顺序表数据
void SLPrint(SL* ps)
{
	if (!ps)
	{
		printf("empty ptr!\n");
		return;
	}
	if (ps->size == 0)
	{
		printf("顺序表为空!\n");
		return;
	}
	printf("当前顺序表数据为:");
	for (int i = 0; i < ps->size; ++i)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
	return;
}

i.首先要判断传入的顺序表指针是否为空。一来可以保证程序合理合法运行,二来也可以消除VS的警告(ps可能为空指针)。

ii.判断顺序表是否有数据。没有数据就没必要打印了。

iii.循环遍历顺序表来打印

结语

看完这篇博客,相信你已经对算法复杂度有了深刻认识了。有什么疑问和困惑欢迎来评论区留言!!🤩我一定尽力及时解答!!制作不易,求关注!!求点赞!!之后还会有更多有用的干货博客会发出哦!!欢迎做客我的主页!!❤❤Elnaij-CSDN博客❤❤

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

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

相关文章

javaweb基础知识入门

javaweb 1.基本概念 1.1前言 web开发&#xff1a; web&#xff0c;网页的意思&#xff0c;www.baidu.com 静态web html&#xff0c;css 提供给所有人看的数据始终不会发生变化&#xff01; 动态web 淘宝...等几乎是所有的网站 提供给所有人看的数据始终会发生变化&#…

使用freepik的retouch功能修改图片

1、准备好需要修改的图片。 2、打开网页&#xff1a;Freepik Retouch - Free AI image editor 3、upload第一步的图片。 4、选择retouch选项。 5、涂抹需要修改的地方。 6、输入提示词。 点击“retouch”按钮。 看结果&#xff1a;

HBase 在统一内容平台业务的优化实践

作者&#xff1a;来自 vivo 互联网服务器团队-Leng Jianyu、Huang Haitao HBase是一款开源高可靠性、扩展性、高性能和灵活性的分布式非关系型数据库&#xff0c;本文围绕数据库选型以及使用HBase的痛点展开&#xff0c;从四个方面对HBase的使用进行优化&#xff0c;取得了一些…

目标识别与跟踪系统

1.资源分配 串口通讯 PA.9 USART1_TX PA.10 USART1_RX OLED显示 PB8,PB.9 状态指示灯 PC.13 按键 PA0光标向下 PA1光标向上 C15确认 C14返回上一级菜单 舵机PWM PA2左右舵机 PA3上下舵机 剩余引脚 PA4,5,6,7,8,11,12,15 PB0,1,3,4,5,6,7,12,13,14,15 2.硬…

水库大坝安全监测险情主要内容

水库常见险情主要包括洪水漫顶、脱坡滑坡、坝体裂缝、 散浸、渗漏、漏洞、陷坑、管涌等&#xff0c;此外风浪冲击、水流冲刷等也会加剧险情的扩大。大坝险情万一抢护不及时&#xff0c;易导致发 生溃坝事故&#xff0c;造成极为严重的灾难性后果。要做到及时有效地 抢护大坝险情…

学习网络的第一步:全面解析OSI与TCP/IP模型

我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货! Hello,大家好!我是你们的好朋友小米。今天我们来聊一聊网络基础知识中的重量级选手——OSI模型和TCP/IP模型!网络的世界就像一个巨大的迷宫,而这两个…

CSS 中的 ::before 和 ::after 伪元素

目录 一、CSS 伪元素 二、::before ::after 介绍 1、::before 2、::after 3、content 常用属性值 三、::before ::after 应用场景 1、设置统一字符 2、通过背景添加图片 3、添加装饰线 4、右侧展开箭头 5、对话框小三角 6、插入icon图标 一、CSS 伪元素 CSS伪元…

C++系列-Vector(一)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” Vector的介绍及使用 Vector的介绍 当vector构建的参数类型为char类型时&#xff0c;它是和string是极其类似的&#xff0c;但是二者之间也有不同&#xff0c;比如&#xff0c…

在conda的环境中安装Jupyter及其他软件包

Pytorch版本、安装和检验 大多数软件包都是随Anaconda安装的&#xff0c;也可以根据需要手动安装一些其他软件包。 目录 创建虚拟环境 进入虚拟环境 安装Jupyter notebook 安装matplotlib 安装 pandas 创建虚拟环境 基于conda包的环境创建、激活、管理与删除http://t.cs…

04:定时器

定时器 1、定时器怎么定时2、怎样实现计数&#xff1f;2.1、控制寄存器TCON2.2、工作模式寄存器TCOM2.3、定时器T0 3、案例&#xff1a;通过定时器T0控制LED间隔1s亮灭 当定时器用的时候&#xff0c;靠内部震荡电路数数。当配置为定时器使用时&#xff0c;每经过1个机器周期&am…

全国排名第一的起名大师颜廷利:唯有量力而行,才能。。。

在探索成功与个人成长的旅程中&#xff0c;中国传统哲学提供了一个独特的视角&#xff1a;量力而行&#xff0c;以展现最靓丽的自我。这一理念不仅深植于中国丰富的文化传统之中&#xff0c;而且与现代社会的实用主义不谋而合。 中国最受欢迎的起名大师颜廷利教授&#xff0c;一…

雷士护眼大路灯值得买吗?书客、雷士、琪朗三大护眼落地灯横评实测!

雷士护眼大路灯值得买吗&#xff1f;随着生活水平的提高&#xff0c;更多的人开始关注养生和视力健康&#xff0c;而护眼大路灯因为有能够提高光线质量&#xff0c;也能用来盖上长期用眼造成眼部干涩、酸痛等症状也越来越受消费者青睐。而现在的护眼大路灯市场&#xff0c;品牌…

先导微型雕刻机XD1213创造更多可能性

打造一间现代化教育装备的校园木工创客室&#xff0c;使木工制作、创意设计、科技融合与教育实践于一体的多功能空间&#xff0c;对校园木工创客室配备一些列的木工设备和工具&#xff0c;以满足不同层次的木工制作需求。 校园木工创客室的空间布局应合理、有序&#xff0c;便于…

【鸿蒙学习笔记】关系型数据库概述

目录标题 关系型数据库的运行机制样例代码共通方法 DBUtilsIndex 代码效果 关系型数据库的运行机制 1、 关系型数据库对应用提供通用的操作接口&#xff0c;底层使用SQLite作为持久化存储引擎&#xff0c;支持SQLite具有的数据库特性&#xff0c;包括但不限于事务、索引、视图…

精密制造,光纤激光打标机在电子通讯行业的深度实践

光纤激光打标机&#xff0c;作为激光加工领域的一项先进技术&#xff0c;近年来在电子通讯行业中得到了广泛应用。它利用掺稀土元素玻璃光纤作为增益介质的激光器&#xff0c;通过光纤放大器开发出高功率密度的激光束&#xff0c;对工件表面进行精细加工&#xff0c;形成永久性…

强制升级最新系统,微软全面淘汰Win10和部分11用户

说出来可能不信&#xff0c;距离 Windows 11 正式发布已过去整整三年时间&#xff0c;按理说现在怎么也得人均 Win 11 水平了吧&#xff1f; 然而事实却是&#xff0c;三年时间过去 Win 11 占有率仅仅突破到 29%&#xff0c;也就跳起来摸 Win 10 屁股的程度。 2024 年 6 月 Wi…

Visual Studio 2022 安装及使用

一、下载及安装 VS 官网&#xff1a;Visual Studio: IDE and Code Editor for Software Developers and Teams 下载免费的社区版 得到一个.exe文件 右键安装 选择C开发&#xff0c;并修改安装位置 等待安装 点击启动 二、VS的使用 1.创建项目 打开VS&#xff0c;点击创建新项…

Ubuntu22.04安装NIVIDIA显卡驱动总结

1.首先在安装驱动时需要判断系统有无GPU以及GPU的型号 可以参考这篇文章&#xff1a; https://blog.51cto.com/u_13171517/8814753#:~:textubuntu%20%E7%B3%BB%E7%BB%9F%20%E6%80%8E%E4%B9%88%E5%88%A4%E6%96%AD%E7%B3%BB%E7%BB%9F%E6%9C%89%E6%B2%A1%E6%9C%89GPU%201%20%E6%…

批量提取PDF中表格内容

1 背景 从PDF文件获取表格中的数据&#xff0c;也是日常办公容易涉及到的一项工作。比如我们想获取某公司年报里面的表格数据&#xff0c;PDF动辄上百页的数据。 2 传统方法 一个一个从PDF表格中复制&#xff0c;然后粘贴到Excel表格中&#xff0c;效率太低了。 3 办公自动…

【OC】巧用UIStackView简化布局

UIStackView的运用 文章目录 UIStackView的运用引入UIStackView的作用UIStackView的属性compression resistance 和 huggingaxisalignmentDistributionspacing UIStackView的方法UIStackView的示例 引入 在仿写ZARA的过程之中&#xff0c;我看到软件之中是有大量的按钮排列在一…