顺序表(一)(数据结构)

news2024/11/29 2:51:33

一. 线性表

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

二. 顺序表的实现

2.1 概念与结构

上面讲了线性表的概念,那什么是顺序表呢?顺序表其实就是线性表的一种,是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况采用数组存储。所以问题这就来了,顺序表在逻辑结构上线性的,那在物理结构上是线性的还是非线性的?这里就要看看顺序表的底层逻辑,上面也说了顺序表是物理地址连续存储单元,所以在物理结构上也是线性的。

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

2.2.1 静态顺序表

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

#define N 7
typedef int SLDataType;
typedef struct SepList 
{
	SLDataType  a[N];  //定长数组
	int size;          //有效数据个数
}SL;

上面的代码就是一个静态顺序表,在这个顺序表中我们使用tyoedef重新定义int类型,其作用就是在我们需要替换int类型的时候我们可以按我们的需求进行替换,不用逐个来换,使用Ctrl+h一键替换,使用#define对N进行定义,size记录真正的有效个数,也就是说我们使用静态顺序表的时候是已经提前知道了数组的元素个数。静态顺序表缺陷:空间给少了不够用,给多了造成空间浪费

2.2.2 动态顺序表

静态顺序表在空间的大小上是固定的,还不够灵活,这个时候就需要动态顺序表这个更有优势的,可以动态申请空间。

typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* a;
	int size;      //有效数据个数
	int capacity;  //空间容量
}SL;

2.2 动态顺序表的实现

上面只是一个动态顺序表结构体,但如果要真正实现一个动态顺序表,我们所需要考虑的东西就多了,我们为了让代码清晰可见,在VS中创建一个头文件SeqList.h,用来定义顺序表的结构和声明要提供的操作,再创建一个SeqList.c文件,用来实现各种操作,一个test.c文件,用来测试函数

在创建顺序表的时候我们要进行多次测试,比如当我们写好初始化的时候就可以进行一次测试,在测试函数test.c中的初始化SLInit中传入的是s的地址,使用的是传址调用,因为如果是传值调用,那么形参pa的值是不影响实参s的值,这一点我们要注意。

尾部 / 头部插入数据

 

 上面的是对顺序表的尾插和头插,以及它们打印出来的结果,在 尾插和头插的时候我们第一要关注的是空间是否足够第二就是我们的数组不能是空指针。在我们空间不够的时候我们使用realloc来申请空间,原因是就是realloc可以返回新空间的起始地址,然后就是在申请空间的时候推荐2倍申请,这样的话空间就不会过于浪费。

尾部 / 头部删除数据

对于删除数据来说,有尾删和头删,大家可能对于尾删来说有点疑问,那么为什么直接pa->size--就可以呢?比如现在有一个数组包含数据1  2  3  4 ,那么现在我要删除4这个数据,我们知道size是指向有效数据的下一个位置,也就是4的后面一个位置,那么现在我让size--就会让size指向4的位置,当我们打印的时候这个位置的数据就不是有效的数据了,而且在尾部插入数据的时候在空间充足的时候我们是直接将新的数据元素之直接插在size的位置上,然后再让size++。对于头删的话我们就用将所有元素整体向前移动一位即可。

任意位置插入 / 删除数据

在指定位置删除或者插入数据的时候,我们一定要注意不是是空指针。 

完整代码

SeqList.h:

//顺序表,(动态顺序表)
//一般我们会有头文件和.c文件用来实现各种操作
//定义动态顺序表结构
#include <stdio.h>
#include <stdlib.h>//申请空间

//如果后期要改变int的类型,为了方便,我们进行重命名
typedef int SLDatatype;
typedef struct SeqList
{
	SLDatatype* arr;
	int capacity;  //空间大小
	int size;  //有效数据个数
}SL;

//初始化
void SLInit(SL* pa);
//销毁
void SLDestory(SL* pa);
//打印数据
void SLPrintf(SL* pa);
//插入数据
void SLPushBack(SL* pa,SLDatatype x);   //尾部插入
void SLPopBack(SL* pa);                 //尾部删除
void SLPushFront(SL* pa, SLDatatype x); //头部插入
void SLPopFront(SL* pa);                //头部删除
void SLInsert(SL* pa, SLDatatype x, int pos);//任意位置之前插入数据
void SLErase(SL* pa, int pos);//删除指定位置的数据

SeqList.c:

//顺序表(动态顺序表)
//一般我们会有头文件和.c文件用来实现各种操作
#include "SeqList.h"
//初始化
void SLInit(SL* pa)
{
	pa->arr = NULL;
	pa->size = pa->capacity = 0;
}
//销毁
void SLDestory(SL* pa)
{
	if (pa != NULL)
	{
		free(pa->arr);
	}
	pa->arr = NULL;
	pa->size = pa->capacity = 0;
}


//判断空间是否足够
void SLCheckcapacity(SL* pa)
{
	if (pa->size == pa->capacity)
	{
		//增容 0*2=0,若capacity为0,给个默认值,否则*2倍
		int newcapacity = pa->capacity == 0 ? 4 : 2 * pa->capacity;
		SLDatatype* tmp = realloc(pa->arr, newcapacity * sizeof(SLDatatype));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		pa->arr = tmp;
		pa->capacity = newcapacity;
	}
}
//插入数据
void SLPushBack(SL* pa, SLDatatype x)//尾插数据
{
	//判断pa是否为空指针
	if (pa == NULL)
	{
		return;
	}
	//判读空间是否足够
	SLCheckcapacity(pa);
	pa->arr[pa->size] = x;
	pa->size++;
}
void SLPushFront(SL* pa, SLDatatype x)//头插数据
{
	//判断pa是否为空指针
	if (pa == NULL)
	{
		return;
	}
	//判读空间是否足够
	SLCheckcapacity(pa);
	//数据整体向后移动一位
	for (int i = pa->size; i >= 0; i--)
	{
		pa->arr[i] = pa->arr[i- 1];
	}
	pa->arr[0] = x;
	pa->size++;
}
//删除数据
#include <assert.h>
void SLPopBack(SL* pa)//尾删
{
	assert(pa);
	assert(pa->size);
	pa->size--;
}
void SLPopFront(SL* pa)//头删
{
	assert(pa);
	assert(pa->size);
	//数据整体向前挪动一位
	for (int i = 0;i<pa->size-1; i++)
	{
		pa->arr[i] = pa->arr[i + 1];
	}
	pa->size--;
}

//任意位置之前插入数据
void SLInsert(SL* pa, SLDatatype x, int pos)
{
	assert(pa);
	assert(pos >= 0 && pos <= pa->size);
	//空间检查
	SLCheckcapacity(pa);
	//pos及之后的数据整体向后移动一位
	for (int i = pa->size; i > pos; i--)
	{
		pa->arr[i] = pa->arr[i - 1];
	}
	pa->arr[pos] = x;
	pa->size++;
}
//删除指定位置的数据
void SLErase(SL* pa, int pos)
{
	assert(pa);
	assert(pos >= 0 && pos < pa->size);
	//pos之后的数据整体向前移动一位
	for (int i=pos;i<pa->size-1;i++)
	{
		pa->arr[i] = pa->arr[i + 1];
	}
	pa->size--;
}


//打印数据
void SLPrintf(SL* pa)
{
	for (int i = 0; i < pa->size; i++)
	{
		printf("%d ", pa->arr[i]);
	}
	printf("\n");
}

test.c:

//测试
#include "SeqList.h"
void SLtest01()
{
	SL s;
	SLInit(&s);//初始化
	SLPushBack(&s, 1);//尾插数据
	SLPushBack(&s, 2);
	SLPushBack(&s, 3);
	SLPushBack(&s, 4);
	SLPopBack(&s);
	SLPrintf(&s);

	//SLPushFront(&s, 1);//头插数据
	//SLPushFront(&s, 2);
	//SLPushFront(&s, 3);
	//SLPushFront(&s, 4);
	SLPrintf(&s);
	SLDestory(&s);
}

int main()
{
	SLtest01();
	return 0;
}

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

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

相关文章

HCIP--1

同一区域内的OSPF路由器拥有一致的 LSDB, 在区域内&#xff0c;OSPF 采用 SPF算法计算路由一个区域太多路由器&#xff0c;硬件资源跟不上&#xff0c;所以多划分区域 OSPF 路由计算原理 1. 区域内路由计算 LSA 在OSPF中&#xff0c;每个路由器生成 LSA&#xff0c;用于告诉…

【部署篇】RabbitMq-03集群模式部署

一、准备主机 准备3台主机用于rabbitmq部署&#xff0c;文章中是在centos7上安装部署rabbitmq3.8通过文章中介绍的方式可以同样在centos8、centos9上部署&#xff0c;只需下载对应的版本进行相同的操作。 主机IP角色说明192.168.128.31种子节点192.168.128.32普通节点192.16…

Matlab学习01-矩阵

目录 一&#xff0c;矩阵的创建 1&#xff0c;直接输入法创建矩阵 2&#xff0c;利用M文件创建矩阵 3&#xff0c;利用其它文本编辑器创建矩阵 二&#xff0c;矩阵的拼接 1&#xff0c;基本拼接 1&#xff09; 水平方向的拼接 2&#xff09;垂直方向的拼接 3&#xf…

Linux系统基础-进程间通信(5)_模拟实现命名管道和共享内存

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 Linux系统基础-进程间通信(5)_模拟实现命名管道和共享内存 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨…

LeetCode--删除并获得点数--动态规划

一、题目解析 二、算法原理 根据题意&#xff0c;在选择了元素 x 后&#xff0c;该元素以及所有等于 x−1 或 x1 的元素会从数组中删去。若还有多个值为 x 的元素&#xff0c;由于所有等于 x−1 或 x1 的元素已经被删除&#xff0c;我们可以直接删除 x 并获得其点数。因此若选…

Win10+MinGW13.1.0编译Qt5.15.15

安装windows SDK、python、ruby、cmake、Perl[可选]安装MySQL解压qt-everywhere-opensource-src-5.15.15.zip&#xff08;注&#xff1a;不要使用qt-everywhere-opensource-src-5.15.15.tar.xz&#xff09;修改源代码 E:\qt-everywhere-src-5.15.15\qtbase\src\3rdparty\angle\…

hive数据库,表操作

1.创建; create database if not exists myhive; use myhive; 2.查看: 查看数据库详细信息:desc database myhive; 默认数据库的存放路径是 HDFS 的&#xff1a; /user/hive/warehouse 内 补充:创建数据库并指定 hdfs 存储位置:create database myhive2 location /myhive2 3.…

<项目代码>YOLOv8路面垃圾识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

Codeforces Round 881 (Div. 3)(A~F1题解)

这场比赛可能是因为比较老吧&#xff0c;我感觉很轻松&#xff0c;就是第五个卡了一下&#xff0c;看错题了&#xff0c;原本应该是严格大于的&#xff0c;从而导致代码一直出现bug&#xff0c;在1小时20分钟才解决 A. Sasha and Array Coloring 题意&#xff1a;就是说给你n个…

提权 | Windows系统

文章目录 cmd提权meterpreter提权getsystemsteal_tokenmigrate 令牌窃取(MS16-075)烂土豆提权步骤烂土豆提权原理 sc命令提权抓本地密码提权其他工具pr工具 内核提权WindowsVulScan cmd提权 前言&#xff1a;我们getshell一个用windows部署的网站后&#xff0c;通过蚁剑或者其…

ESP32 S3 语音识别 语音唤醒程序流程

ESP32 S3 语音识别 语音唤醒程序流程 参考例程首先进行esp_periph_set_init 初始化之后执行setup_player&#xff0c;之后执行start_recorder&#xff0c;识别的主处理voice_read_task 参考例程 D:\Espressif\esp-adf\examples\speech_recognition\wwe\ 首先进行esp_periph_se…

零知识学习WLAN漫游二、无线漫游介绍(2)

接前一篇文章&#xff1a;零知识学习WLAN漫游一、无线漫游介绍&#xff08;1&#xff09; 本文内容参考&#xff1a; WLAN漫游简介_漫游主动性-CSDN博客 无线漫游_百度百科 无线漫游简述-CSDN博客 特此致谢&#xff01; 一、WLAN漫游简介 3. 漫游协议和快速漫游协议 802.…

算法的学习笔记—数字在排序数组中出现的次数(牛客JZ53)

&#x1f600;前言 在编程中&#xff0c;查找有序数组中特定元素的出现次数是一个常见的问题。本文将详细讲解这个问题的解决方案&#xff0c;并通过二分查找法优化效率。 &#x1f3e0;个人主页&#xff1a;尘觉主页 文章目录 &#x1f970;数字在排序数组中出现的次数&#x…

九、pico+Unity交互开发——触碰抓取

一、VR交互的类型 Hover&#xff08;悬停&#xff09; 定义&#xff1a;发起交互的对象停留在可交互对象的交互区域。例如&#xff0c;当手触摸到物品表面&#xff08;可交互区域&#xff09;时&#xff0c;视为触发了Hover。 Grab&#xff08;抓取&#xff09; 概念&#xff…

深入浅出:深度学习模型部署全流程详解

博主简介&#xff1a;努力学习的22级计算机科学与技术本科生一枚&#x1f338;博主主页&#xff1a; Yaoyao2024往期回顾&#xff1a; 【论文精读】PSAD&#xff1a;小样本部件分割揭示工业异常检测的合成逻辑每日一言&#x1f33c;: 生活要有所期待&#xff0c; 否则就如同罩在…

【国潮来袭】华为原生鸿蒙 HarmonyOS NEXT(5.0)正式发布:鸿蒙诞生以来最大升级,碰一碰、小艺圈选重磅上线

在昨日晚间的原生鸿蒙之夜暨华为全场景新品发布会上&#xff0c;华为原生鸿蒙 HarmonyOS NEXT&#xff08;5.0&#xff09;正式发布。 华为官方透露&#xff0c;截至目前&#xff0c;鸿蒙操作系统在中国市场份额占据 Top2 的领先地位&#xff0c;拥有超过 1.1 亿 的代码行和 6…

想让前后端交互更轻松?alovajs了解一下?

作为一个前端开发者&#xff0c;我最近发现了一个超赞的请求库 alovajs&#xff0c;它真的让我眼前一亮&#xff01;说实话&#xff0c;我感觉自己找到了前端开发的新大陆。大家知道&#xff0c;在前端开发中&#xff0c;处理 Client-Server 交互一直是个老大难的问题&#xff…

查缺补漏----用户工作区,系统缓冲区,外设工作最短时间计算

对于下面这一题&#xff0c;分析起来很简单&#xff1a; 答案&#xff1a;C 以上是单缓冲区&#xff0c;补充双缓冲区是什么情况&#xff1a; 1.假设磁盘块与缓冲区大小相同&#xff0c;每个盘块读入缓冲区的时间为15us&#xff0c;由缓冲区送至用户区的时间是5us&#xff0c…

etl-查询错误log日志和oracle删除数据表空间

查看weblogic日志的目录 建立连接ssh root192.168.30.1xx 密码hygd123 找到下面路径中的文件 cd /home/weblogic/Oracle/Middleware/user_projects/domains/base_domain/bapp-logs 查看log日志 tail -f -n 400 Adminservers.log oracle删除表空间&#xff08;切换到dba用户…

Android 13 SystemUI 隐藏下拉快捷面板部分模块(wifi,bt,nfc等)入口

frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java createTileInternal(tileSpec)方法注释想隐藏的模块即可。