【数据结构】动态顺序表的实现

news2024/9/19 9:57:12

1.什么是数据结构

数据结构就是把数据元素按照一定的关系组织起来的集合,用来组织和存储数据。通过数据结构,能够有效的将数据组织和管理在一起,按照我们的方式任意对数据进行增删查改等操作。

2.数据结构的分类 

数据结构大概可分为逻辑结构物理结构两大类 。

2.1逻辑结构 

逻辑结构:是从具体问题中抽象出来的模型,是抽象意义的结构。

  • 集合结构:结构中数据元素除了同属于一个集合外,它们之间没有任何关系
  • 线性结构:结构中数据元素之间存在一一对应的关系
  • 树形结构:结构中数据元素之间存在一对多的层次关系
  • 图形结构:结构中数据元素是多对多的关系

2.2物理结构 

物理结构:逻辑结构在计算机中真正的表示方式(又称映像)。

常见的物理结构(存储结构)有顺序存储链式存储索引存储,以及散列存储

  • 顺序存储结构:把数据元素放到地址连续的内存单元里面,其数据间的逻辑关系和物理关系是一致的,比如我们常用的数组就是顺序存储结构。
  • 链式存储结构:是把数据元素存放在任意的存储单元里面,这组存储单元可以是连续的,也可以是不连续的。此时,数据间的物理关系不能反映其逻辑关系。所以每一数据元素均使用一个结点来存储,不仅需要存储数据元素,而且还要存储数据元素之间的逻辑关系(将结点分为两部分,一部分存储数据元素本身,称为数据域;一部分存储下一个结点的地址,称为指针域。
  • 索引存储结构:在索引存储结构中,不仅需要存储所有数据元素(称为主数据表),还需要建立附加的索引表。每个数据元素都由一个唯一的关键字来标识,由该关键字和对应的数据元素的地址构成一个索引项,存入索引表。
  • 散列(哈希)存储结构:散列存储结构是指依据数据元素的关键字,通过事先设计好的哈希函数计算出一个值,再将其作为该数据的存储地址。

2.3总结 


最基础的数据结构:数组

有了数组,为什么还要学习其他的数据结构?

假定数组有10个空间,已经使用了5个,向数组中插入数据步骤:

求数组的有效数据个数,向下标为数据有效个数的位置插入数据。(注意:这里要判断数组是否满了)

假设数据量非常庞大,频繁的获取数组有效数据个数会影响程序执行效率。

结论:最基础的数据结构能够提供的操作已经不能完全满足复杂算法实现。


3.线性表

线性表(linear list)指的是具有部分相同特性的一类数据结构的集合。

线性表的逻辑结构属于线性结构,采用顺序存储结构为顺序表,采用链式存储结构为线性链表顺序表在C语言中一般使用数组去实现,链表使用结构体去实现


3.1顺序表

顺序表的底层结构是数组,通过对数组的封装,实现了常用的增删改查等接口。

3.2顺序表的分类

静态顺序表

概念:使用定长数组存储元素

//静态顺序表
typedef int SLDATATYPE;
#define N 100
typedef struct SeqList
{
	SLDATATYPE arr[N];//定长数组
	int size;//顺序表当前有效数据个数
}SL;

静态顺序表缺陷静态顺序表的长度是固定的,因此数组满了需要手动更改N,空间给少了不够用,给多了造成空间浪费。

动态顺序表

//动态顺序表——按需申请  可增容
typedef int SLDATATYPE;
typedef struct SeqList
{
	SLDATATYPE* arr;//指向动态开辟的数组
	int size;//顺序表当前有效数据个数
	int capacity;//记录当前空间大小
}SL;

3.3动态顺序表的实现

3.3.1顺序表的初始化

void SLInit(SL *ps)//注意:这里不可以写成void SLInit(SL ps)
                   //会报错:使用了未初始化的局部变量!这是值传递,对形参的修改不影响实参。要传地址
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

3.3.2顺序表的销毁

顺序表的销毁
void SLDestory(SL* ps)
{
	if (ps->arr)
	{
		free(ps->arr);//先释放空间,然后置空
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

3.3.3顺序表的插入

尾插

注意:插入数据之前先看空间够不够。初始化后空间容量为0,插入数据之前先申请空间,也可能空间满了,有效数据个数等于空间容量了,也要申请空间。

容量检查函数

void SLCheckCapacity(SL*ps)
{
	//插入数据之前先看空间够不够
	if (ps->capacity == ps->size)
	{
		//申请空间		
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//三目表达式
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * 2 * sizeof(SLDataType));//要申请多大空间
		//若要频繁的增容,则会造成程序的运行效率大大降低,增容通常来说是成倍数的增加,一般是2或者3倍
		//realloc申请空间失败返回空指针,所以再造一个临时的指针tmp
		if (tmp == NULL)
		{
			perror("realloc");
			exit(1);//直接退出程序
		}
		//空间申请成功
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
}

尾插实现 

void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	ps->arr[ps->size++] = x;//增加一个数据,有效数据个数+1
	/*ps->arr[ps->size] = x;
	++ps->size;*/
}

头插

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];//最后一次ps->arr[1]=ps->arr[0]
		}
		ps->arr[0] = x;
		ps->size++;
}

3.3.4顺序表的删除

尾删

void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);//判断顺序表是否为空,为空不能执行删除操作
	//顺序表不为空
	--ps->size;
}

注意:被删除的数据空间不需要置为0,没有意义,下次访问这块空间时,新的数据会覆盖掉。也不能释放空间,因为free只能从开辟的空间的首地址处释放,不能释放其他地方的空间。


头删

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

3.3.5在指定位置插入数据

void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
    //让pos及之后的数据整体向后挪动一位
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];//最后一次ps->arr[pos+1]=ps->arr[pos]
	}
	ps->arr[pos] = x;
	ps->size++;
}

3.3.6删除指定位置的数据

void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	for (int i = pos; i < ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];//最后一次ps->arr[size-2]=ps->arr[size-1]
	}
	ps->size--;
}

3.3.7顺序表的查找

int SLFind(SL* ps, SLDataType x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->arr[i] ==x)
		{
			//找到了!
			return i;
		}
	}
	//没有找到!
	return -1;
}

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

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

相关文章

拆分因子+减枝

前言&#xff1a;一开始看到数据量这么大&#xff0c;我怎么拆分出因子&#xff0c;看了题解才发现要大减枝&#xff0c;但是如何拆分因数我还是要好好学一下 1 0 18 10^{18} 1018 的拆分因子有 1 0 5 10^5 105 的复杂度&#xff0c;再乘以 1 0 3 10^3 103 的数量&#xff0c…

光伏电站设备设施巡视卡之转变二维码登记卡

光伏电站作为重要的能源供应设施&#xff0c;其稳定运行和高效维护至关重要&#xff0c;光伏电站巡回检查制度是保障电站设备正常运行和安全性的重要手段,制定好的制度可以提高电站的经济效益和安全性。 传统的纸质光伏电站巡视卡容易出现巡检记录作假、信息统计不及时、汇总困…

分享一个基于python的零食销售数据采集与可视化分析系统django爬虫项目大数据源码(源码、调试、LW、开题、PPT)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人 八年开发经验&#xff0c;擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等&#xff0c;大家有这一块的问题可以一起交流&…

国产实时操作系统:和RT-Linux,Zephyr的实时性对比

RT-Thread 在工业领域、高安全高可靠性领域&#xff0c;实时操作系统在其中发挥着重要的作用&#xff0c;从毫秒级&#xff0c;微秒级实时响应&#xff0c;决定着装置系统能满足何种严苛的要求。 RT-Thread Smart操作系统是一套基于RT-Thread内核&#xff0c;并具备POSIX用户态…

LeetCode84(柱状图中最大的矩形)理解单调栈

1. LeetCode84(柱状图中最大的矩形) 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights [2,1,5,6,2,3] 输出&#xff…

大模型时代,什么样的算法工程师更吃香?

毫无疑问&#xff0c;全栈型的算法工程师将更为抢手&#xff0c;如果你精通大模型从训练到应用的整个流程&#xff0c;你走到哪里都不怕。 但往往人的精力有限&#xff0c;如果从数据、预训练、微调、对齐、推理、应用几个方面来看的话&#xff0c;个人觉得现在重要性排序是“…

python测试框架之Pytest

初识Pytest Pytest1.Pytest的特点&#xff1a;2.Pytest的基本使用规则3.pytest安装1&#xff09;使用编译器安装2&#xff09;使用命令安装 4.pytest规则 Pytest Pytest是python的一个第三方单元测试库&#xff0c;它的目的是让单元测试变得容易&#xff0c;并且也能扩展到支持…

同一个wifi不同电脑ip一样吗?网络ip地址怎么修改

‌在数字化时代&#xff0c;Wi-Fi已成为我们日常生活与工作中不可或缺的一部分&#xff0c;它让多台设备能够轻松接入互联网&#xff0c;实现信息共享与数据传输。然而&#xff0c;你是否曾好奇过&#xff0c;在同一个Wi-Fi网络下&#xff0c;不同电脑的IP地址是否会不一样&…

10个Python自动化日常任务实战脚本示例

小编准备入门了Python入门学习籽料80个Python入门实例 点击 领取&#xff08;无偿获得&#xff09; 1. 自动备份文件夹 目标 : 每天自动将指定文件夹的内容备份到另一个位置。 import shutil import datetime def backup_files(source, destination): """…

DevEcoStudio创建的默认工程HelloWorld build失败请问如何解决?

解决方法&#xff1a; 方法一&#xff1a; 方法二&#xff1a; 确认当前登录的windows用户是否是Administrator&#xff0c;出现这种情况&#xff0c;大概率都是普通用户&#xff0c;所以造成权限不足的问题。一种解决办法是切换到Administrator用户再打开项目进行build。 如…

已拿证 | 2024深圳驾考科目四全攻略:技巧、知识点一网打尽

目录 _head 精简500题 区分变道和左转&#xff0c;变道手下垂&#xff0c;左转手伸直 紧急包扎需要柔软介质 网状线内禁止停车 会车千万不能开远光灯 只准直行 城3公4 城5公7 一急二反三连续 落水救援 驾驶陋习 车到路肩人在外 交警先看脸&#xff01;&#xff01…

Redis保姆级安装教程

下载:https://github.com/redis-windows/redis-windows/releases 然后就慢慢等待 下载完解压,打开 以管理员身份运行,这里一直按回车就可以了 复制路径 这里勾错了,是编辑 修改配置文件redis.conf 加这一行 以管理员身份运行cmd,输入redis-cli 在输入ping 再输入info 这样就完…

IP-RDS-222、IP-PRZ-59-AM12、EG-TRZ-42-L、EG-TRZ-42-H比例减压阀放大器

IP-DAR-250、IP-DAR-43C-L、IP-DAR-43C-H、IP-RDS-222、IP-PRZ-59-AM12、EG-TRZ-42-L、EG-TRZ-42-H比例减压阀 EE-PRB、EE-PRD比例压力阀 EE-P2G、ET-P2S、EB-P2A、EE-P2A、ET-P2A、EE-P2H、EG-F2A、EU-F2A比例流量阀 EF-F3G、EU-F3G比例压力补偿流量阀 EQ-S4M、EG-S4M、EQ…

【JAVA CORE_API】Day21 Map接口、在线聊天室v3.0、Java的反射机制(P1)

Map接口 Map接口 Map是Java中用于存储键值对&#xff08;key-value pairs&#xff09;的接口&#xff0c;每个键&#xff08;key&#xff09;对应一个值&#xff08;value&#xff09;。它不允许重复的键&#xff0c;但允许不同的键映射相同的值。 关键特点&#xff1a; 键值…

Linux 可视化管理工具:宝塔面板(BT)

&#x1f600;前言 在 Linux 系统的运维管理中&#xff0c;命令行界面&#xff08;CLI&#xff09;是主要的操作方式。然而&#xff0c;对于许多系统管理员或开发者来说&#xff0c;使用 CLI 进行管理和维护任务并不总是最直观或最方便的方式。为了简化操作并提高效率&#xff…

【注解】反序列化时匹配多个 JSON 属性名 @JsonAlias 详解

JsonAlias 注解是 Jackson 提供的一个功能强大的注解&#xff0c;允许一个字段在反序列化时匹配多个 JSON 属性名。它适用于在处理多种输入数据格式时&#xff0c;或当 JSON 数据的键名可能变化时。 一、JsonAlias 的作用 多种别名&#xff1a;JsonAlias 允许你为一个字段定义…

利用深度学习技术来实现街景图像的语义分割(街景图像语义分割)

本项目致力于利用深度学习技术来实现街景图像的语义分割。通过精确地识别和分类图像中的每个像素&#xff0c;该技术能够自动划分出街道、人行道、车辆、行人等各种不同的物体类别。这在智能交通系统、自动驾驶、城市规划等领域有着广泛的应用前景。 技术实现 深度学习模型&am…

网站上线流程完全手册:域名、服务器与CDN

网站上线的核心要点 需要买域名 域名备案(国内) 买服务器 把服务器IP和域名(网址)绑定 把本地网站代码文件上传到服务器上 我来先来了解下以上的概念 域名介绍 域名是网站的地址&#xff0c;类似于你的家在街上的位置。它让人们通过简单的名字&#xff08;如 www.baidu.…

大模型时代的AI应用开发,可以不用,但必须会

成熟的“格子衫”和年轻的“脸庞”&#xff0c;与开发者有关的大会总是少不了这两种元素&#xff0c;Create 2024百度AI开发者大会也不例外。 过去几十年&#xff0c;层出不穷的编程语言、框架等新技术&#xff0c;把一代又一代年轻的脸庞&#xff0c;塑造为成熟的格子衫&…

网络安全威胁2024年中报告

近日&#xff0c;奇安信威胁情报中心发布《网络安全威胁2024年中报告》&#xff0c;内容涵盖高级持续性威胁&#xff08;APT&#xff09;、勒索软件、互联网黑产、漏洞利用等几方面。 APT攻击活动&#xff1a;2024 年上半年&#xff0c;APT 攻击主要集中在信息技术、政府、科研…