【顺序表的实现】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

前言

1. 数据结构相关概念

1、什么是数据结构

2、为什么需要数据结构?

2、顺序表 

1、顺序表的概念及结构

1.1 线性表

2、顺序表分类

3、动态顺序表的实现

总结


前言

世上有两种耀眼的光芒,一种是正在升起的太阳,一种是正在努力学习编程的你!一个爱学编程的人。各位看官,我衷心的希望这篇博客能对你们有所帮助,同时也希望各位看官能对我的文章给与点评,希望我们能够携手共同促进进步,在编程的道路上越走越远!


提示:以下是本篇文章正文内容,下面案例可供参考

1. 数据结构相关概念

1、什么是数据结构

先来看两张图片

数据结构是由“数据”和“结构”两词组合而来。

什么是数据?

常见的数值1、2、3、4.....、教务系统里保存的用户信息(姓名、性别、年龄、学历等等)、网页里肉眼可以看到的信息(文字、图片、视频等等),这些都是数据。

什么是结构?

当我们想要使用大量使用同一类型的数据时,通过手动定义大量的独立的变量对于程序来说,可读性非常差,我们可以借助数组这样的数据结构将大量的数据组织在一起,结构也可以理解为组织数据的方式。

想要找到草原上名叫“咩咩”的羊很难,但是从羊圈里找到1号羊就很简单,羊圈这样的结构有效将 羊群组织起来。

概念:数据结构是计算机存储、组织数据的方式数据结构是指相互之间存在一种或多种特定关系 的数据元素的集合。数据结构反映数据的内部构成,即数据由那部分构成,以什么方式构成,以及数据元素之间呈现的结构。

总结:

1)能够存储数据(如顺序表、链表等结构)

2)存储的数据能够方便查找

2、为什么需要数据结构?

还是先来看一张图片

如图中所示,不借助排队的方式来管理客户,会导致客户就餐感受差、等餐时间长、餐厅营业混乱等情况。同理,程序中如果不对数据进行管理,可能会导致数据丢失、操作数据困难、野指针等情况。

通过数据结构,能够有效将数据组织和管理在一起。按照我们的方式任意对数据进行增删改查等操 作。

最基础的数据结构:数组。

数组
012345

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

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

求数组的长度,求数组的有效数据个数,向下标为数据有效个数的位置插入数据(注意:这里是 否要判断数组是否满了,满了还能继续插入吗).....

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

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

2、顺序表 

1、顺序表的概念及结构

1.1 线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的, 线性表在物理上存储时,通常以数组和链式结构的形式存储。

案例:蔬菜分为绿叶类、瓜类、菌菇类。线性表指的是具有部分相同特性的一类数据结构的集合如何理解逻辑结构和物理结构?

2、顺序表分类

• 顺序表和数组的区别

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

接口:我们后续提供给其他用户使用的函数或方法

• 顺序表分类

◦ 静态顺序表(缺陷:空间给少了不够用,给多了造成空间浪费)

◦ 动态顺序表

3、动态顺序表的实现

(1)头文件 —— (顺序结构的创建和相关操作函数的定义或声明,起目录作用)

SeqList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
//动态顺序表
//类型重命名(要加分号)
//如果我们要转换类型的话,就可以直接替换int
typedef int SLDataType;  
typedef struct Seqlist
{SLDataType* a;int size;  //顺序表中有效的数据个数 = 最后一个数据的下一个位置(因为位置的话,有下标0)int capacity;  //顺序表中当前的空间大小
}SL;//对结构体类型初始化
//sl是结构体类型创建的变量
void SLInit(SL* ps);//销毁顺序表
void SLDestroy(SL* ps);//头部/尾部 插入或删除
void SLPushBack(SL* ps, SLDataType x);
//我们在顺序表中尾部插入一个SLDataType类型的数据x
void SLPushFront(SL* ps, SLDataType x);//头部插入void SLPopBack(SL* ps);//尾部删除
void SLPopFront(SL* ps);//头部删除//打印数据
void SLprint(SL* ps);//当把顺序表都初始化为0,而没有尾插和头插的话,就直接进行尾删,代码会报错
//判断顺序表是否为空
bool SLIsEmpty(SL* ps);//在任意位置插入数据
//在指定的位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x);
//删除指定位置的数据
void SLErase(SL* ps, int pos);//在数据表中查找数据
bool SLFind(SL* ps, SLDataType x);

(2) 源文件 —— (顺序表相关函数的具体实现)

test.c

//接口:我们后续提供给其他用户使用的函数或方法
#include "seqlist.h"
void SLInit(SL* ps)
{ps->a = NULL;ps->size = ps->capacity = 0;
}//销毁顺序表
void SLDestroy(SL* ps)
{//动态内存开辟了空间才能free()释放if(ps->a!=NULL)free(ps->a);ps->a = NULL;ps->size = ps->capacity = 0;
}//判断当前顺序表的空间是否足够
void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){//结构体变量指向的有效数据个数==顺序表当前空间的大小,就得扩容//realloc()函数的第二个参数:顺序表当前空间的大小 * 2倍 * SLDataType的类型//首先得判断一下顺序表中当前空间的大小是否为0,因为为0的话,0*任何数都是0int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));if (tmp == NULL){perror("realloc");return 1;}ps->a = tmp;ps->capacity = newcapacity;//顺序表当前空间的大小赋值给capacity,一个空间大小是SLDataType类型的}
}//头部/尾部 插入或删除
void SLPushBack(SL* ps, SLDataType x)
{assert(ps != NULL);//1:空间足够,直接尾插//2:空间不够,扩容//直接调用扩容函数SLCheckCapacity(ps);//直接插入数据ps->a[ps->size] = x;ps->size++;
}
//头插
void SLPushFront(SL* ps, SLDataType x)
{assert(ps != NULL);//判断空间是否足够的函数//空间不够,扩容SLCheckCapacity(ps);//空间足够,历史数据向后移一位for (size_t i = ps->size; i > 0; i--){ps->a[i] = ps->a[i - 1]; }ps->a[0] = x;//第0个位置直接插入xps->size++;//既要增加数据,也要增加空间
}void SLPopBack(SL* ps)//尾部删除
{assert(ps != NULL);assert(!SLIsEmpty(ps));//SLIsEmpty(ps):如果为真,就进入函数,那么顺序表就为空//SLIsEmpty(ps):为真,加!就为假,那么断言执行,否则就不执行ps->a[ps->size - 1] = 0;ps->size--;
}
void SLPopFront(SL* ps)//头部删除
{assert(ps);assert(!SLIsEmpty(ps));//让后面的数据往前挪动一位for (size_t i = 0; i <ps->size-1; i++){//如果数组下标为ps->size的话,就越界了//因为size为有效数据的个数 = 最后一个数据的下一个位置(有下标为0)ps->a[i] = ps->a[i + 1];}ps->size--;
}//打印数据
void SLprint(SL* ps)
{for (size_t i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}//判断顺序表是否为空
bool SLIsEmpty(SL* ps)
{assert(ps != NULL);return ps->size == 0;//如果当前没有一个有效的数据,就为空
}//在任意位置插入数据
//在指定的位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{//pos的位置对于计算机看来是下标的意思assert(ps);//不要忘了对pos加以限制assert(pos >= 0 && pos <= ps->size);//怕有人会在-100之类的位置插入数据//扩容SLCheckCapacity(ps);//把pos位置及以后的数据往后挪动一位//循环条件里的i的初始值是size还是size-1都是可以的,但不同的初始值对应不同的结束条件for (size_t i = ps->size; i > pos; i--){//最后一个进来的值是pos+1ps->a[i] = ps->a[i - 1];}ps->a[pos] = x;ps->size++;
}
//删除指定位置的数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(!SLIsEmpty(ps));//要对pos进行限制assert(pos >= 0 && pos < ps->size);for (int i = pos; i < ps->size - 1; i++){//最后一次进来的数据是ps->size-2(ps->size的话,就越界了)ps->a[i] = ps->a[i + 1];//ps->a[size-2] = ps->a[size-1]}ps->size--;
}//在数据表中查找数据
bool SLFind(SL* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->a[i] == x){return true;}}return false;
}

(3) 源文件 —— (顺序表的测试)

test1.c

#define _CRT_SECURE_NO_WARNINGS 1#include "seqlist.h"void SLtest()
{SL sl;//定义一个顺序表,sl就是没有初始化//SLInit(sl);//我们把sl传递给一个初始化的方法进行初始化SLInit(&sl);//我们想要把sl初始化的话,要把地址传过去,因为形参是实参的一份临时拷贝//顺序表的具体操作//尾插SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//1 2 3 4SLprint(&sl);//头插SLPushFront(&sl, 5);//5 1 2 3 4 SLPushFront(&sl, 6);//6 5 1 2 3 4SLPushFront(&sl, 7);//7 6 5 1 2 3 4SLprint(&sl);//尾删SLPopBack(&sl);SLprint(&sl);SLPopBack(&sl);SLprint(&sl);//销毁顺序表SLDestroy(&sl);
}
void SLtest02()
{SL sl;SLInit(&sl);SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLprint(&sl);//头删SLPopFront(&sl);SLprint(&sl);SLPopFront(&sl);SLprint(&sl);	SLPopFront(&sl);SLprint(&sl);//到这里顺序表已经没有数据了SLPopFront(&sl);SLprint(&sl);//在任意位置插入数据//在指定的位置之前插入数据SLInsert(&sl, sl.size, 11);SLprint(&sl);//删除指定位置的数据SLErase(&sl, 0);SLprint(&sl);//在数据表中查找数据bool Findret = SLFind(&sl, 3);if (Findret == 3){printf("找到了!\n");}else{printf("找不到!\n");}//销毁顺序表SLDestroy(&sl);
}int main()
{//测试顺序表是否被初始化SLtest();SLtest02();return 0;
}


总结

好了,本篇博客到这里就结束了,如果有更好的观点,请及时留言,我会认真观看并学习。
不积硅步,无以至千里;不积小流,无以成江海。

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

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

相关文章

6. hdfs的命令操作

简介 本文主要介绍hdfs通过命令行操作文件 操作文件有几种方式&#xff0c;看个人习惯 hdfs dfs hdfs fs hadoop fs个人习惯使用 hadoop fs 可操作任何对象&#xff0c;命令基本上跟linux命令一样 Usage [hadoophadoop01 ~]$ hadoop fs Usage: hadoop fs [generic option…

【广州华锐互动VRAR】VR元宇宙技术在气象卫星知识科普中的应用

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;和元宇宙等技术正逐渐走进我们的生活。这些技术为我们提供了一个全新的互动平台&#xff0c;使我们能够以更加直观和生动的方式了解和学习各种知识。在气象天文领域&#xff0c;VR元宇宙技术的应用也日益显现…

Gin框架源码解析

概要 目录 Gin路由详解 Gin框架路由之Radix Tree 一、路由树节点 二、请求方法树 三、路由注册以及匹配 中间件含义 Gin框架中的中间件 主要讲述Gin框架路由和中间件的详细解释。本文章将从Radix树&#xff08;基数树或者压缩前缀树&#xff09;、请求处理、路由方法树…

SDUT OJ《算法分析与设计》贪心算法

A - 汽车加油问题 Description 一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法&#xff0c;指出应在哪些加油站停靠加油&#xff0c;使沿途加油次数最少。并证明算法能产生一个最优解。 对于给定的n和k个加油站位置&#xff0c;计算最少加油次数。 I…

23.11.19日总结

经过昨天的中期答辩&#xff0c;其实可以看出来项目进度太慢了&#xff0c;现在是第十周&#xff0c;预计第十四周是终级答辩&#xff0c;在这段时间要把项目写完。 前端要加上一个未登录的拦截器&#xff0c;后端加上全局的异常处理。对于饿了么项目的商品建表&#xff0c;之前…

JavaEE进阶学习:Spring 的创建和使用

Spring 就是⼀个包含了众多工具方法的 IoC 容器。既然是容器那么它就具备两个最基本的功能&#xff1a; 将对象存储到容器&#xff08;Spring&#xff09;中从容器中将对象取出来 接下来使用 Maven 方式来创建一个 Spring 项目&#xff0c;创建 Spring 项目和 Servlet 类似&a…

ERR_PNPM_INVALID_WORKSPACE_CONFIGURATION packages field missing or empty

vue执行 pnpm install命令时&#xff0c;报 ERR_PNPM_INVALID_WORKSPACE_CONFIGURATION  packages field missing or empty错&#xff0c;在网上查询了很久&#xff0c;也没有传出来结果&#xff0c;最后发现是pnpm的版本不对引起的。 我先执行的是npm install -g pnpm&…

卡尔曼滤波器在车流量检测中的应用

目录 1. 作者介绍2. 卡尔曼滤波器2.1 卡尔曼滤波概述2.2 标志性发展2.3 卡尔曼公式理解 3. 车流量检测3.1 背景介绍3.2 实现过程3.2.1 YOLOv3网络模型结构3.2.2 SORT算法3.2.3 基于虚拟线圈法的车辆统计 4. 算法实现4.1 Kalman.py4.2 完整代码4.3 结果展示 1. 作者介绍 吴思雨…

星火模型(Spark)的langchain 实现

星火模型的langchain实现 测试已通过&#xff0c;希望有所帮助。 使用前请先安装环境&#xff1a; pip install githttps://github.com/shell-nlp/spark-ai-python.git注意&#xff1a; 一定要使用上面方式安装spark库&#xff0c;因对官方的库做了改动。官方的库已经长时间不…

〖大前端 - 基础入门三大核心之JS篇㊳〗- DOM访问元素节点

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;不渴望力量的哈士奇(哈哥)&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xf…

基于DOTween插件实现金币飞行到指定位置功能

文章目录 前言一、DOTween是什么&#xff1f;二、使用步骤1.导入DOTween插件在Unity官方插件商店找到DOTween插件导入DOTween插件启用DOTween插件 2.代码逻辑金币飞行代码控制飞行效果代码 3.物体配置1.物体上装配CoinEffect脚本2.在金币预制体上装配FlyControl脚本 三、效果展…

Web安全研究(五)

Automated WebAssembly Function Purpose Identification With Semantics-Aware Analysis WWW23 文章结构 introbackgroundsystem design abstraction genapplying abstractionsclassifier data collection and handling data acquisitionstatistics of collected datamodule-…

回归预测 | Matlab实现HPO-ELM猎食者算法优化极限学习机的数据回归预测

回归预测 | Matlab实现HPO-ELM猎食者算法优化极限学习机的数据回归预测 目录 回归预测 | Matlab实现HPO-ELM猎食者算法优化极限学习机的数据回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现HPO-ELM猎食者算法优化极限学习机的数据回归预测&#xff08;…

pytorch.nn.Conv1d详解

通读了从论文中找的代码&#xff0c;终于找到这个痛点了&#xff01; 以下详解nn.Conv1d方法 1 参数说明 in_channels(int) – 输入信号的通道。 out_channels(int) – 卷积产生的通道。 kernel_size(int or tuple) - 卷积核的尺寸&#xff0c;经测试后卷积核的大小应为in_cha…

AR眼镜_单目光波导VS双目光波导方案

双目光波导AR眼镜方案是一种创新的智能设备&#xff0c;可以在现实场景中叠加虚拟信息&#xff0c;提供增强的视觉体验和交互体验。光学显示方案是AR眼镜的核心技术之一&#xff0c;它对眼镜的性能和使用体验起着决定性的作用。 相比于单目AR眼镜&#xff0c;双目AR眼镜具有更好…

【嵌入式 – GD32开发实战指南(ARM版本)】第2部分 外设篇 - 第3章 温度传感器DS18B20

1 理论分析 1.1 DS18B20概述 DS18B20 是 DALLAS 最新单线数字温度传感器,新的"一线器件"体积更小、适用电压更宽、更经济。Dallas 半导体公司的数字化温度传感器 DS1820 是世界上第一片支持 "一线总线"接口的温度传感器。 DS18B20采用的单总线协议,也…

Git详解及 github使用

1.1 关于版本控制 开始之前先看一个没有版本控制的例子 1.1.1 本地版本控制 本地版本控制系统 许多人习惯用复制整个项目目录的方式来保存不同的版本&#xff0c;或许还会改名加上备份时间以示区别。这么做唯一的 好处就是简单&#xff0c;但是特别容易犯错。有时候会混淆所在…

YOLOv5 学习记录

文章目录 整体概况数据增强与前处理自适应Anchor的计算Lettorbox 架构SiLU激活函数YOLOv5改进点SSPF 模块 正负样本匹配损失函数 整体概况 YOLOv5 是一个基于 Anchor 的单阶段目标检测&#xff0c;其主要分为以下 5 个阶段&#xff1a; 1、输入端&#xff1a;Mosaic 数据增强、…

简单聊一聊幂等和防重

大家好&#xff0c;我是G探险者。 每年的双十一&#xff0c;618&#xff0c;电商系统都会面临这超高的流量&#xff0c;如果一个订单被反复提交&#xff0c;那电商系统如何保证这个订单之后执行一次减库存&#xff0c;扣款的操作&#xff1f; 这里就引入两个概念&#xff0c;…

下一代搜索引擎会什么?

现在是北京时间2023年11月18日。聊一聊搜索。 说到搜索&#xff0c;大家首先想到的肯定是谷歌&#xff0c;百度。我把这些定义成上一个时代的搜索引擎。ChatGPT已经火热了有一年的时间了&#xff0c;大家都认为Ai搜索是下一代的搜索。但是AI搜索&#xff0c;需要的是很大算力&a…