【初阶数据结构】详解顺序表(下)(顺序表的代码实现)

news2024/9/21 12:30:55

文章目录

  • 前言
  • 1. 项目文件的配置
    • 1.1 顺序表的项目的文件配置(仅供参考)
  • 2. 顺序表的代码实现
    • 2.1 SeqList.h:
    • 2.2 SeqList.c:
      • 2.2.1 顺序表初始化的代码实现:
      • 2.2.2 顺序表销毁的代码实现:
      • 2.2.3 顺序表尾插数据的代码实现:
      • 2.2.4 顺序表头插数据的代码实现:
      • 2.2.5 顺序表尾删的代码实现:
      • 2.2.6 顺序表头删的代码实现:
      • 2.2.7 顺序表打印的函数代码实现:
      • 2.2.8 顺序表在指定位置之前插入数据的代码实现:
      • 2.2.9 删除顺序表中指定位置的数据的代码实现:
      • 2.2.10 查找数据在顺序表中的所处的位置代码实现:
    • 2.3 test.c
  • 3. 写代码时注意的细节

前言

在详解顺序表(上)中,给大家讲解了数据结构的定义,数据结构就是计算机存储和管理数据的方式。我还讲解了何为线性表,以及顺序表的基础概念。那么本文将具体讲解如何用代码来实现顺序表。不要眨眼哦。

哈哈哈

1. 项目文件的配置

在正式写代码之前,如果我们项目之下的子文件能够配置好的话,不仅能让我们的代码看上去更加的美观,而且还能大大提高我们编程的效率。

什么意思呢?且听我慢慢道来。

在我们创建.c源文件和.h头文件时,它们是允许被创建多个的,学过变编译与链接这个知识点的就知道其原理。那我们可以这样想:

我们之前无论是写main函数还是其他的函数都是在一个.c文件中的,那假设如果我们现在要写一个很多代码的项目,那我们是不可能讲这么多的代码都写到一个.c文件中的,因为这毕竟是要给别的程序员看的。那如果我们也为文件建立其功能加以区分,那这样不就达成我们的目的了。

话不多说,我们马上开干。

1.1 顺序表的项目的文件配置(仅供参考)

顺序表的文件配置
具体操作如下(以VS为例):
图1
图2
图3

OK,创建项目工程任务实现了现在我们正式开始编写顺序表的代码!!!
哈哈哈

2. 顺序表的代码实现

先直接给出代码,让大家思考为什么要这样写,后面我会全部向大家讲解代码编写时容易踩的坑。

如果时间比较紧张的读者可以直接拷贝去使用。

2.1 SeqList.h:

//SeqList.h里面的内容是顺序结构的定义以及实现顺序表操作各接口的声明
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define MAX 100
//静态顺序表的声明
//struct SeqList
//{
//	int arr[MAX];//定长的数组
//	int size;//记录当前数组有效的数据个数
//};


//动态顺序表的声明(两者之间,推荐使用这个)
typedef int SLDataType;
typedef struct SeqList
{
	//int* arr; //这里我们存的数据不只是int类型的,因此我们应该这么写
	SLDataType* arr;
	int size; //当前的有效数据个数
	int capacity; //空间大小
}SL;

//打印顺序表中的数据
void SLPrint(SL s);

//初始化顺序表
void SLInit(SL* ps);

//销毁顺序表
void SLDestory(SL* ps);

//添加数据到顺序表中
//1.尾插
void SLPushBack(SL* ps, SLDataType x);

//2.头插
void SLPushFront(SL* ps, SLDataType x);

//删除数据
//1.头删
void SLPopFront(SL* ps);

//2.尾删
void SLPopBack(SL* ps);

//指定位置之前添加数据
void SLInsert(SL* ps, int pos, SLDataType x);

//删除指定位置的数据
void SLErase(SL* ps, int pos);

//找出指定数据所处的位置
int SLFind(SL* ps,SLDataType x);

2.2 SeqList.c:

2.2.1 顺序表初始化的代码实现:

void SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

2.2.2 顺序表销毁的代码实现:

void SLDestory(SL* ps)
{
	if (ps->arr)
	{
		free(ps->arr);
		ps->arr = NULL;
	}
	ps->size = ps->capacity = 0;
}

2.2.3 顺序表尾插数据的代码实现:

void SLCheckCapacity(SL* ps)
{
	assert(ps);
	//空间不足时,申请空间
	if (ps->capacity == ps->size)
	{
		SL* tmp = NULL;
		int newscapacity = (ps->capacity) == 0 ? 2 : 2 * (ps->capacity);
		tmp = realloc(ps->arr, newscapacity * sizeof(SLDataType));

		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(1);
		}

		//申请成功
		ps->arr = tmp;
		ps->capacity = newscapacity;
	}
}

void SLPushBack(SL* ps, SLDataType x)
{
	
	SLCheckCapacity(ps);
	ps->arr[ps->size++] = x;
}

2.2.4 顺序表头插数据的代码实现:

void SLPushFront(SL* ps, SLDataType x)
{
	SLCheckCapacity(ps);//这里的函数在尾插代码中有

	int i = 0;
	for (i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i-1];
	}

	ps->arr[0] = x;
	ps->size++;
}

2.2.5 顺序表尾删的代码实现:

void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->arr);

	ps->size--;
}

2.2.6 顺序表头删的代码实现:

void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->arr);

	int i = 0;
	for (i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}

	ps->size--;
}

2.2.7 顺序表打印的函数代码实现:

void SLPrint(SL s)
{
	int i = 0;
	for (i = 0; i < s.size; i++)
	{
		printf("%d ",s.arr[i]);
	}
	printf("\n");
}

2.2.8 顺序表在指定位置之前插入数据的代码实现:

void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && ps->size > pos);
	SLCheckCapacity(ps);


	if (pos == 0)
	{
		SLPushFront(ps, x);
	}
	else
	{
		int i = 0;
		for (i = ps->size; i > pos; i--)
		{
			ps->arr[i] = ps->arr[i - 1];
		}

		ps->arr[pos] = x;

		ps->size++;
	}

}

2.2.9 删除顺序表中指定位置的数据的代码实现:

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

	ps->size--;
}

2.2.10 查找数据在顺序表中的所处的位置代码实现:

int SLFind(SL* ps, SLDataType x)
{
	assert(ps);

	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (ps->arr[i] == x)
		{
			return i;
		}
	}

	//未找到
	return -1;
}

2.3 test.c

这个文件里的内容可按照自己的测试下想法来编写main函数里面的内容,这里我就不过多展示了。

3. 写代码时注意的细节

总结上面代码中比较容易出错的地方:
1.

图1

这里我为什么会用typedef给int起别名?

原因有二:
第一:我们所说的顺序别是能够存储各种数据类型的,不仅仅局限于整型数据,还有可能是字符型数据、浮点型数据甚至是自定义类型。
第二:用typedef所起别名的变量有助于我们后期对代码的维护,只要我们想更改顺序表所存储的数据类型,我们能一步动作就实现一次性的更改。

  1. 以这一个函数为例
    图2

这个函数的形参为什么是就够结构体指针类型的,不能是结构体类型的吗?

答案是不能的。原因如下:
在调用函数时,我们向函数传递参数时,有两种方式:

  1. 传值调用:只是将调用函数时给变量的值传递给了形参,而形参是存储在操作系统给的另一片空间中。本质是:形参是实参的一份临时拷贝
  2. 传址调用:会改变调用函数所传递变量的值。其本质就是通过地址找到该变量,从而进行修改。

针对上面的描述,我想你已经知道为什么我这里会选择传址调用了。

图3

这里主要是注意if的条件判断,有些读者可能会这么写:

if(ps->capacity == 0)
{
	...
}

注意这种写法仅仅只是考虑到了初始化顺序表的情况,但是没有考虑到可用空间与有效数据个数之间的关系。

到这里,顺序表的代码实现就已经全部讲解完毕了。如果觉得本文不错的话,麻烦给偶点个赞吧!!!💖💖💖

哈哈

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

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

相关文章

【国赛必看!】数学建模python基础教学及常用算法代码包分享

一、内容介绍 Python在各个编程语言中比较适合新手学习&#xff0c;Python解释器易于扩展&#xff0c;可以使用C、C或其他可以通过C调用的语言扩展新的功能和数据类型。 Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库&#xff0c;提供了适用于各个主要系统…

opencv-python图像增强六:低光照增强

文章目录 一&#xff1a;简介二、低光照图像增强方案&#xff1a;三、算法实现步骤3.1 CLAHE直方图均衡化&#xff1a;3.2 伽马变换&#xff1a;3.3 对亮度通道做伽马变换 四&#xff1a;整体代码实现五&#xff0c;效果&#xff1a; 一&#xff1a;简介 低光照图像增强是一种…

Flink 常见问题汇总:反压积压,checkpoint报错,窗口计算,作业报错,无产出,流批不一致,调优等。

Flink 常见问题汇总 0 如何分析日志0.1作业内部重启异常&#xff0c; 作业正常运行0.2 作业内部重启&#xff0c; 但作业已经手动 kill 整个 yarn-application0.3 作业失败&#xff0c;整个 yarn application 结束运行 1 Flink 作业积压排查流程及解决思路1 反压原因2 反压的危…

Windows下搭建Telegraf+Influxdb+Grafana(详解一)

InfluxDB&#xff08;时序数据库&#xff09;&#xff0c;常用使用场景&#xff1a;监控数据统计。 grafana&#xff0c;用作监控页面的前端展示。 telegraf&#xff0c;数据采集器。 所有的安装包都上传到网盘 链接: https://pan.baidu.com/s/1Lv6UnfueK7URx7emAatoYg 提取…

oracle 数据中lsnrctl 是干啥的

突然发现lsnrctl stop 之后&#xff0c;依然可以启动数据库 就感觉怪怪的&#xff0c;一直以为这个是数据库的守护进程&#xff0c;原来不是。。。。 lsnrctl 是 Oracle 监听器控制实用程序的命令行界面工具&#xff0c;用于管理 Oracle Net 服务监听器。监听器是 Oracle 网络…

map和set的应用

map、set 1. 序列式和关联式容器2.set和multiset2.1 构造2.2 迭代器2.3 修改 3. map和multimap3.1 map3.2. multimap 1. 序列式和关联式容器 序列式容器&#xff1a;比如&#xff1a;vector、list、deque、forward_list等&#xff0c;这些容器统称为序列式容器&#xff0c;因为…

Vue3+Echarts+饼图环形图

记得给容器宽高 <div id"leftChartguawang" style"height: 28vh"></div> 配置函数 const leftChartguawang () > {const chartBox echarts.init(document.getElementById(leftChartguawang))let datas [[{ name: 居民节能建筑, value…

SmartEDA电路仿真软件革新力作:重塑电子设计界,揭秘其爆红背后的秘密武器!

在这个日新月异的科技时代&#xff0c;每一场技术革新都是推动行业进步的强劲动力。而在电子设计领域&#xff0c;一款名为SmartEDA的电路仿真软件正以前所未有的姿态&#xff0c;颠覆传统设计模式&#xff0c;成为众多工程师和设计师争相追捧的新宠。今天&#xff0c;就让我们…

硬核详解FutureTask设计与实现

写在文章开头 最近看到一篇比较不错的FutureTask实践,于是对FutureTask源码进行了研究,而本文将从实践和源码两个角度分析FutureTask的设计与实现思路,希望对你有帮助。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源项目 …

从零开始搭建 EMQX 集群压测框架

从零开始搭建 EMQX 集群压测框架 架构 在设计以EMQX为中心的MQTT消息队列集群压力测试框架时&#xff0c;我们采用微服务架构模式。EMQX作为消息队列的核心&#xff0c;负责处理MQTT协议的消息发布和订阅。Nginx作为EMQX的反向代理&#xff0c;负责负载均衡和SSL/TLS终端。MQT…

农业上的目标跟踪论文汇总

文章目录 2022Multi-object tracking using Deep SORT and modified CenterNet in cotton seedling counting (Computers and Electronics in Agriculture)A novel apple fruit detection and counting methodology based on deep learning and trunk tracking in modern orcha…

模型部署 - docker

docker简介 Docker 是一种开源的容器化平台&#xff0c;允许开发者将应用程序及其依赖项打包到一个标准化的单元中&#xff0c;称为“容器”。这些容器可以在任何支持 Docker 的系统上运行&#xff0c;无需担心环境差异。 为什么需要 Docker&#xff1f; 在传统的开发中&…

ECharts数据可视化 数据集与事件 入门基础知识【2】

echarts一个基于 JavaScript 的开源可视化图表库。其有丰富的图表类型、强大的渲染引擎、专业多维度的数据分析、灵活配置的可视化设计。关于echarts的下载安装以及在项目中使用的基础知识我们前面已经回顾过了&#xff1a; ECharts 数据可视化 入门基本知识 下载安装常用的图表…

计数排序以及排序总结

技数排序 计数排序又称为鸽巢原理&#xff0c;是对哈希直接定址法的变形应用。 思路&#xff1a; 统计相同元素出现次数根据统计的结果将序列回收到原来的序列中 void CountSort(int* arr, int n) {//寻找最大、最小值int maxarr[0], min arr[0];for (int i 0; i < n;…

【网络】私有IP和公网IP的转换——NAT技术

目录 引言 NAT工作机制​编辑 NAT技术的优缺点 优点 缺点 个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 引言 公网被子网掩码划分为层状结构&#xff0c;一个公网IP的机器又可以用很多私有IP搭建内网。在日常生活场景中用的都是私有IP&#xff0c;例如手机&#xff0c;…

单元训练05:独立按键的基本操作

可以正常运行的&#xff1a; #include "stc15f2k60s2.h"#define LED(x) \{ \P0 x; \P2 P2 & 0x1f | 0x80; \P2 & 0x1f; \}void Timer0_Init(void) // 1毫秒12.000MHz {AUXR | 0x80; …

spring boot 发送微信小程序订阅消息

首先我们需要订阅一个消息&#xff1a; 订阅教程本文章并未提起&#xff0c;感兴趣的同学自行百度。 我们可以看到订阅消息中【消息内容】有很多参数&#xff0c;我们在发送消息时就需要将这些参数进行填充&#xff0c;当然填充的时候要注意格式&#xff0c;如果格式不对还是会…

python字符串方法,格式化字符串format,字符串的编码和解码,字符串的拼接

字符串–不可变序列 1.字符串方法 2.格式化字符串format&#xff0c;通过格式化字符串解决不同数据类型链接时候报错的问题例如用连接字符串和int就会报错 ①占位符需要注意格式print ( ’ 结果:%s %d ’ % (user_inp,ans))&#xff0c;注意需要给输出语句“”,后边需要有%。…

HarmonyOS应用开发者高级认证(一)

1、依次点击A、B、C、D四个按钮&#xff0c;其中不会触发UI刷新的是&#xff1a; 答案&#xff1a; Button("C").onClick(() > {this.nameList[0].name "Jim"})分析&#xff1a;直接更新非一级数据不会触发UI刷新 2、如果要实现Row组件内的子元素均匀…

wish怎么提升店铺流量?自养号测评防关联技术全解析

在电商领域&#xff0c;Wish作为一家知名的跨境电商平台&#xff0c;店铺流量的提升对于商家来说至关重要&#xff0c;如若店铺流量不够的话排名也会比较靠后&#xff0c;这时候卖家就需要做好相关运营政策去提升流量。 一、Wish怎么提升店铺流量&#xff1f; 1、优化商品信息…