顺序表详解

news2024/11/15 19:30:47

💓博主个人主页:不是笨小孩👀
⏩专栏分类:数据结构与算法👀
🚚代码仓库:笨小孩的代码库👀
⏩社区:不是笨小孩👀
🌹欢迎大家三连关注,一起学习,一起进步!!💓

顺序表

  • 线性表
  • 什么是顺序表呢?
  • 静态顺序表
  • 动态顺序表
  • 接口实现
    • 那么有哪些接口呢?
      • 初始化
      • 打印
      • 销毁顺序表
      • 尾删
      • 尾插
      • 头删
      • 头插
      • 查找
      • 在下标pos的位置插入数据
      • 删除pos位置的数据
      • 修改pos位置的元素为x

在这里插入图片描述

线性表

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

什么是顺序表呢?

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表分为静态顺序表和动态顺序表,我们重点讲动态的,因为实用性更大。

静态顺序表

使用定长的数组来存储数据。

//  静态
#define MAX 100

typedef int SLDateType;

typedef struct SeqList
{
	SLDateType arr[MAX];
	int size;  // 有效数据的个数
}SL;

在这里插入图片描述

动态顺序表

使用动态开辟的数组存储。

// 动态
typedef int SLDateType;

typedef struct SeqList
{
	SLDateType* arr;
	int size;      // 有效数据的个数
	int capacity;  // 容量空间的大小
}SeqList;

在这里插入图片描述

接口实现

那么有哪些接口呢?

// 对数据的管理:增删查改 
// 顺序表的初始化
void SeqListInit(SeqList* ps);

// 顺序表销毁
void SeqListDestroy(SeqList* ps);

// 顺序表打印
void SeqListPrint(SeqList* ps);

// 顺序表尾插
void SeqListPushBack(SeqList* ps, SLDateType x);

// 顺序表头插
void SeqListPushFront(SeqList* ps, SLDateType x);

// 顺序表头删
void SeqListPopFront(SeqList* ps);

// 顺序表尾删
void SeqListPopBack(SeqList* ps);

// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);

// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x);

// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);

接下来我们来一一的实现这些接口。

初始化

我们这里主要讲的是动态的顺序表,我们假定刚开始给顺序表设置为4个元素,不够用我们就扩容。

//初始化
void SeqListInit(SeqList* ps)
{
//防止ps为空指针
	assert(ps);
	ps->arr = (SLDateType*)malloc(sizeof(SLDateType) * 4);
	//判断是够开辟成功
	if (ps->arr == NULL)
	{
		perror("malloc falled");
		return;
	}
	ps->size = 0;
	ps->capacity = 4;
}

打印

打印比较简单,我们只需要遍历一遍顺序表就可以了。

// 打印顺序表
void SeqListPrint(SeqList* ps)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
}

销毁顺序表

我们需要将动态开辟的内存释放了,然后将数据和容量都置为0.

// 销毁顺序表
void SeqListDestroy(SeqList* ps)
{
	assert(ps);
	free(ps->arr);
	ps->size = 0;
	ps->capacity = 0;
}

尾删

尾删只需要将有效数据的个数减少一下就可以了,但是在这之前要判断顺序表中是否有元素,如果没有就没必要删了。

// 尾删
void SeqListPopBack(SeqList* ps)
{
	assert(ps);
	assert(ps->size);
	ps->size--;
}

尾插

尾插只要在size的位置放一个数据就可以了,也是比较简单的。

但是在插入之前我们为了防止容量不够,我们再分装一个函数来判断顺序表是否满了,如果满了我们就扩容。我们这里假设一次扩2倍,这个比较灵活,自己掌握就行。

//扩容
void SLCheckCapacity(SeqList* ps)
{
	if (ps->size == ps->capacity)
	{
		SLDateType* cur = (SLDateType*)realloc(ps->arr, ps->capacity * 2 * sizeof(SLDateType));
		if (cur == NULL)
		{
			perror("realloc");
			return;
		}
		ps->arr = cur;
		ps->capacity *= 2;
	}
}
//尾插
void SeqListPushBack(SeqList* ps, SLDateType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	ps->arr[ps->size] = x;
	ps->size++;
}

头删

我们只需要将后面的数据依次往前挪动,然后将size–就可以了,这里从前往后挪,从后往前挪数据会被覆盖。

//  头删
void SeqListPopFront(SeqList* ps)
{
	assert(ps);
	assert(ps->size);
	int begin = 1;
	while (begin < ps->size)
	{
		ps->arr[begin - 1] = ps->arr[begin];
		begin++;
	}
	ps->size--;
}

头插

这里只需要将数据依次往后挪动,然后将0的位置放入x,然后size++即可。但是在此之前依然要判断顺序表是否满容。

// 头插
void SeqListPushFront(SeqList* ps, SLDateType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	int end = ps->size;
	while (end > 0)
	{
		ps->arr[end] = ps->arr[end - 1];
		end--;
	}
	//循环结束end==0
	ps->arr[end] = x;
	ps->size++;
}

查找

我们遍历顺序表,找到返回下标,找不到返回-1.

// 查找  找到返回下标否则返回-1
int SeqListFind(SeqList* ps, SLDateType x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->arr[i] == x)
		{
			return i;
		}
	}
	return -1;
}

在下标pos的位置插入数据

我们只需要将pos位置到最后的数据依次往后挪动,然后将arr[pos]改为x,size++即可。但是我们依然要判断是否满容。

// 在pos下标位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{
	assert(ps);
	//判断pos是否合法
	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);
	int end = ps->size;
	while (end > pos)
	{
		ps->arr[end] = ps->arr[end - 1];
		end--;
	}
	ps->arr[pos] = x;
	ps->size++;
}

删除pos位置的数据

这个就比较简单了,我们只需要将pos后面的数据依次往前挪,覆盖pos,size–,即可。

// 删除pos下标的数据
void SeqListErase(SeqList* ps, int pos)
{
	assert(ps);
	//判断pos是否合法
	assert(pos >= 0 && pos < ps->size);
	int begin = pos + 1;
	while (begin < ps->size)
	{
		ps->arr[begin - 1] = ps->arr[begin];
		begin++;
	}
	ps->size--;
}

修改pos位置的元素为x

这个直接将arr[pos]改为x就行啦,这里就不给大家实现了。

今天的分享就到这里,感谢大家的关注和支持。

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

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

相关文章

NetApp FAS2750 和 FAS2820:适用于分布式企业和从远程到核心的 FAS

NetApp FAS2750 和 FAS2820&#xff1a;适用于分布式企业和从远程到核心的 FAS 拥有分布式企业和多个办公位置的客户希望使用这些系统进行虚拟化&#xff0c;以及为大型 FAS 和 AFF 系统提供简单且经济高效的备份和灾难恢复。 为什么要从 NetApp FAS 系列中选择一个型号&…

LLM / Python - json 使用详解

目录 一.引言 二.json 方法 1.json.dumps 2.json.dump 3.json.loads 4.json.load 三.json 参数 1.ensure_ascii 2.allow_nan 3.indent 4.sortKeys 5.Other 四.LLM 数据构建 1.json 数据构建 2.Train.py 五.总结 一.引言 上文中我们介绍了 LLama2-Chinese 的简…

ipad手写笔有必要买原装吗?质量好苹果平板平替笔推荐

因为iPad平板的强大&#xff0c;使得很多人群都用上了iPad&#xff0c;而且还在不断的普及。不管是用于绘画或者学习记笔记&#xff0c;都非常好用&#xff0c;但要是用来看电视剧玩游戏就没那么有价值了。如果你不打算购买昂贵的苹果电容笔&#xff0c;或者只是为了记录&#…

“数字中华 点亮未来”中华线上客户节 盛大开幕

2023年是中华保险数字化转型落地之年&#xff0c;峥嵘37载&#xff0c;中华保险在数字化转型上已经涌现了一批彰显辨识度、具有影响力的应用成果。7月15日&#xff0c;中华保险围绕数字化转型之路开展以“数字中华 点亮未来”为主题的37周年线上客户节活动&#xff0c;倾力打造…

直播平台源码开发提高直播质量的关键:视频编码和解码技术

在互联网日益发展的今天&#xff0c;直播平台成为人们互联网生活的主力军&#xff0c;直播平台功能的多样化与智能化使我们的生活有了极大地改变&#xff0c;比如短视频功能&#xff0c;它让我们既可以随时随地去发布自己所拍摄到的东西让世界各地的用户看到&#xff0c;也能让…

融合正余弦和折射反向学习的北方苍鹰优化算法,与金鹰/蜣螂/白鲸/霜冰算法对比...

今天的主角是&#xff1a;融合正余弦和折射反向学习的北方苍鹰优化算法(SCNGO)&#xff0c;算法由作者自行改进&#xff0c;目前应该没有文献这样做。 改进策略参照的上一期改进的麻雀优化算法&#xff0c;改进点如下&#xff1a; ①采用折射反向学习策略初始化北方苍鹰算法个体…

【字节跳动青训营】后端笔记整理-3 | Go语言工程实践之测试

**本文由博主本人整理自第六届字节跳动青训营&#xff08;后端组&#xff09;&#xff0c;首发于稀土掘金&#xff1a;&#x1f517;Go语言工程实践之测试 | 青训营 目录 一、概述 1、回归测试 2、集成测试 3、单元测试 二、单元测试 1、流程 2、规则 3、单元测试的例…

AQS抽象同步队列核心原理

CLH自旋锁 JUC中显式锁基于AQS抽象队列同步器&#xff0c;而AQS是CLH锁的一个变种。队列头结点可以获得锁&#xff0c;其他节点排队等候。 在争夺锁激烈的情况下&#xff0c;为了减少CAS空自旋&#xff08;CAS需要CPU进行内部通信保证缓存一致性造成流量过大引起总线风暴&…

【代码随想录day21】二叉搜索树中的众数

题目 给你一个含重复值的二叉搜索树&#xff08;BST&#xff09;的根节点 root &#xff0c;找出并返回 BST 中的所有 众数&#xff08;即&#xff0c;出现频率最高的元素&#xff09;。 如果树中有不止一个众数&#xff0c;可以按 任意顺序 返回。 假定 BST 满足如下定义&am…

Git移除commit过的大文件

前言&#xff1a;在提交推送本地更改至仓库时&#xff0c;误将大文件给提交了&#xff0c;导致push时报错文件过大&#xff0c;因此需要将已经commit的大文件移除后再push 若已知要删除的文件或文件夹路径&#xff0c;则可以从第4步开始 1.对仓库进行gc操作 $ git gc 2.查询…

ThinkPHP 一对多关联

用一对多关联的前提 多的一方的数据库表有一的一方数据库表的外键。 举例&#xff0c;用户获取自己的所有文章 数据表结构如下 // 用户表 useruser_id - integer // 用户主键name - varchar // 用户名称// 文章表 articlearticle_id - integer // 文章主键title - varchar …

WSL2安装google chrome浏览器

一. 环境: Windows 11 Ubuntu-22.04 二. 安装google-chrome步骤&#xff08;官方文档&#xff09;&#xff1a; 1. 创建文件夹&#xff1a;mkdir chrome 2. 进入目录&#xff1a;cd chrome/ 3. 下载chrome压缩包&#xff1a;sudo wget https://dl.google.com/linux/direct/go…

学习 NestJs 的第一步

安装 NestJS 的先决条件和安装 NestJS NodeJS 的版本需要大于等于 16。 安装 NestJS 的命令是&#xff1a;npm i -g nestjs/cli。 使用命令创建项目 使用 nest new <项目名称> 来创建项目&#xff0c;假如要开启 TS 的严格语法功能的话&#xff0c;可以把--strict 标…

【雕爷学编程】Arduino动手做(93)--- 0.96寸OLED液晶屏模块15

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

OSPF的拓展配置

OSPF的拓展配置 1.手工认证 --- 在OSPF数据包交互中&#xff0c;邻居之间的数据报中将携带认证口令&#xff0c;两边认证口令相同&#xff0c;则意味着身份合法 OSPF的手工认证总共分为三种&#xff1a; 1.接口认证 [r5-GigabitEthernet0/0/0]ospf authenticati…

GB/T 25000.51解读——软件产品的性能效率怎么测?

GB/T 25000.51-2016《软件产品质量要求和测试细则》是申请软件检测CNAS认可一定会用到的一部国家标准。在前面的文章中&#xff0c;我们为大家整体介绍了GB/T 25000.51-2016《软件产品质量要求和测试细则》国家标准的结构和所涵盖的内容以及对软件产品的八大质量特性中的功能性…

fastposter v2.16.0 让海报开发更简单

fastposter v2.16.0 让海报开发更简单 &#x1f525;&#x1f525;&#x1f525; fastposter海报生成器是一款快速开发海报的工具。只需上传一张背景图&#xff0c;在对应的位置放上组件&#xff08;文字、图片、二维&#x1f434;、头像&#xff09; 点击代码直接生成各种语言…

个人信息的编写以及头像的联动

下面这个是导航栏通过on触发的事件 与图片联动 <template><div><ul><li>{{obj.account}}</li><li>{{obj.ctime|dataFormat}}</li><li>{{obj.id}}</li><li>{{obj.userGroup}}</li><div><!-- acti…

VIOOVI精益管理:实现高效运营和持续改进的关键

关于什么是精益化管理这个问题&#xff0c;从字面上理解&#xff0c;“精”为“精良”&#xff0c;“益”为“利益”&#xff0c;意在产品更加精良&#xff0c;利益更加丰厚。而从丰田精益生产中我们可以看出精益化管理绝不是以偏概全的管理&#xff0c;而是全面的结合内部、外…

Linux操作系统~必考面试题⑧

1、pwd 命令 pwd 命令用于查看当前工作目录路径。 实例&#xff1a; 查看当前路径 pwd 查看软链接的实际路径 pwd -P 2、rmdir 命令 从一个目录中删除一个或多个子目录项&#xff0c;删除某目录时也必须具有对其父目录的写权限。 注意&#xff1a;不能删除非空目录实例&…