当前位置: 首页 > news >正文

数据结构-顺序表详解专题

目录

顺序表

1.简单了解顺序表

2.顺序表的分类

2.1静态顺序表

2.2动态顺序表

2.3typedef命名作用

3.动态顺序表的实现

SeqList.h

SeqList.c

test.c


顺序表

1.简单了解顺序表

顺序表是线性表的一种,线性表是在逻辑上是线性结构,在物理逻辑上并不是一定连续的

顺序表的低层结构是数组,对数组的封装,实现了对数据的增删查改等功能。

2.顺序表的分类

顺序表可以分为静态顺序和动态顺序表

2.1静态顺序表

#define MAX 100
typedef int SLDataType;
//静态顺序表
typedef struct SeqList
{SLDataType a[MAX];//这个是开辟100大小的空间,而不是已经使用有效的空间int size; //计算存放的有效数据
}SL;

静态顺序表缺陷:空间给少了不够用会造成数据丢失,给多了造成空间浪费。

2.2动态顺序表

//动态顺序表
typedef struct SeqList
{SLDataType * arr; //类似于数组指针,作为存储数据的低层结构int capacity;//容量,记录顺序表的空间大小,也就是要开辟的空间大小int size;//就是记录当前存放了多少有效数据。
}SL;
//两种相同的命名写法。
//typedef sturuct SeqLits SL;

动态顺序表能够实现需要使用空间时候开辟,这样更方便数据的管理,所以推荐用动态顺序表。

2.3typedef命名作用

为什么要用typedef呢

因为当你写int的一堆代码,如果想要把int改成char类型的时候,如果没用到typedeff的话,就要一个一个的改,如果使用了typedef的话直接修改int 换成char就可以了。

3.动态顺序表的实现

分成了三个板块,分别为SeqList.h , SeqList.c ,test.c

SeqList.h

//动态顺序表
typedef struct SeqList
{SLDataType * arr; //类似于数组指针,作为存储数据的低层结构int capacity;//容量,记录顺序表的空间大小,也就是要开辟的空间大小int size;//就是记录当前存放了多少有效数据。
}SL;
//两种相同的命名写法。
//typedef sturuct SeqLits SL;
void SLinit(SL *ps);
void SLPrint(SL* ps); //打印void SLPushBack(SL * ps ,SLDataType x);  //尾插 
void SLPushFront(SL* ps, SLDataType x);  //头插
void SLCheckcapacity(SL* ps); //扩容void SLPopBack(SL* ps); //尾删
void SLPopFront(SL* ps); //头删void SLInsert(SL* ps, int pos, SLDataType x);//指定位置插入
void SLErase(SL* ps, int pos);//指定位置删除void SLFind(SL* ps, SLDataType x);//查找
void SLDestroy(SL* ps);//销毁void SLAlter(SL* ps, int pos, SLDataType x);//修改数据

SeqList.c

#include "Sqlist.h"
//初始化
void SLinit(SL* ps)
{ps->arr = NULL;ps->capacity = 0;ps->size = 0;}
//打印
void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d  ", ps->arr[i]);}printf("\n");
}/扩容放在这里,因为等下头插也会用到,设置成公共的,减少代码
void SLCheckcapacity(SL *ps)
{//扩容//先判断是不是空间满了if (ps->size == ps->capacity){//扩容先给arr申请开劈空间 SLDataType * arr; //realloc头文件 stdlib.h,  void  realloc (这是要在已有的空间情况下继续扩容,扩容的大小)//ps->arr = (SLDataType*)realloc(ps->arr,2* ps ->capacity  );//扩容2倍2* ps ->capacity//但是上面这个是不可取的,因为ps ->capacity刚刚被初始化现在为0。//因此要事先判断当 ps ->capacity为0 时,要先赋值,如果不为0 那么开辟2倍的空间int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity; //三目运算符/*ps->arr = (SLDataType*)realloc(ps->arr, newcapacity);*///这样写还是不够准确,这个时候newcapacity是比特大小,不是字节,//这个时候要* 一个sizeof(SLDataType),因为要类型的大小字节不同/*ps->arr = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));*///即使这样还是不行,因为你不知道是否申请成功,所以还要创建一个临时变量,然后进行判断realloc是否成功SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));//判断realloc是否申请空间成功if (tmp == NULL)//如果没空那么是没成功{perror("realloc fail!"); //这个为啥这么写还真不知道exit(1); //扩容失败直接中断程序}//到这步说明已经申请空间成功//free(ps->arr);//不需要这个,realloc他会自己销毁ps->arr = tmp;ps->capacity = newcapacity;}
}//尾插
//参数列表中有一个指向SL结构体的指针ps,
//和一个用来存储数据的参数x。
//函数内部先用assert函数判断st是否为空,
//然后判断栈是否已经满了。如果栈满了,
//就进行扩容操作,将原数组大小翻倍(如果原来大小是0则扩容为4),
//然后利用realoc函数重新分配内存空间,并将原数组中的数据拷贝到新的空间中。,拷贝的时候要销毁空间
//最后将数据x压入栈的顶部,并将栈顶指针top加一。
void SLPushBack(SL* ps, SLDataType x) //用来存储数据的参数x,x是用来插入数据的内容
{//assert 如果不成立那么会直接中断报错,并且会说明在哪里错误。//assert(ps);assert(ps != NULL); //温柔的判断解决,不会报错/*if (ps != NULL){return;}*///尾插分为情况//1.第一个是空间已经满了需要扩容//2.第二个是还有空间,直接在尾部,也就是ps -> size 位置插入即可。//空间不够SLCheckcapacity(ps);//空间没有满,直接进行尾插ps->arr[ps->size] = x; //为啥存放到arr里面,那capacity干嘛的//arr是结构体指针指向的是地址然后用来存放内容的,capacity只是用来存放目前空间大小的容量而已ps->size++;}
//头插
void SLPushFront(SL* ps, SLDataType x)
{//头插也是两种情况,一种是满了要开空间,另一种是没满,要把旧数据往后移动,然后留首位置插入assert(ps != NULL);SLCheckcapacity(ps);//将旧数据往后移动,从后面开始移动for (int  i = ps->size ; i > 0 ; i--) //让i指向size位置。{ps->arr[i] = ps->arr[i - 1]; //让i-1位置移动到i位置,就是往后移动一个位置。}ps->arr[0] = x; //首位置放新元素,头插ps->size++;
}//尾删
void SLPopBack(SL* ps)
{//两种情况,第一种是全为空,无法删除,第二种是直接可以删尾部数据assert(ps != NULL);assert(ps->size != 0);//顺序表不能为空//进行第二种情况//ps->arr[ps->size - 1] = NULL; //当size --,那么即使size位置里面有数据,也不会影响打印,插入,删除//因为默认size位置是不进行处理的。相当于看不见等于没有ps->size--;}void SLPopFront(SL* ps)
{//两种情况,第一种是全为空,无法删除,第二种是删除头部,把数据往前移动assert(ps != NULL);assert(ps->size != 0);//顺序表不能为空for (int i = 0 ; i < ps ->size -1 ; i++) //因为size要往前移动一个,i最大只能说ps ->size-2{ps->arr[i] = ps->arr[i + 1];}ps->size--;
}
//在指定位置插入元素
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);//要限制pos的大小,不然会出错,pos要小于size,也要大于0assert(pos >= 0 && pos <= ps->size);//扩容SLCheckcapacity(ps);//首先要知道要插入的pos位置,然后把pos后面的数据往后移动,留pos位置插入for (int i = ps->size; i > pos; i--){//最后一位size,所以从size开始ps->arr[i] = ps->arr[i - 1];//固定句式前面丢给后面}ps->arr[pos] = x;ps->size++;}//指定位置删除
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size );//让pos后面的数据往前移动for (int i = pos ; i < ps->size - 1 ; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}
//查找
void SLFind(SL* ps, SLDataType x)
{assert(ps);//判断顺序表是否为空for (int  i = 0; i < ps->size; i++){if (ps->arr[i] == x)//判断是否有该元素{printf("查找成功,该元素下标为%d \n", i);return;}}//全部查找一遍。printf("查找失败。不存在该元素。 \n");
}//销毁
void SLDestroy(SL* ps)
{//先判断是否为空表,然后释放arr的空间,接着就是让arr指向nullassert(ps);//if (ps->arr != NULL)if (ps->arr){free(ps->arr);}ps->arr = NULL;ps->capacity = ps->size = 0;}
//修改
void SLAlter(SL* ps, int pos, SLDataType x)
{assert(ps);//先找到对应的数据,然后修改for (int i = 0; i < ps->size; i++){if (ps->arr[i] == pos){ps->arr[i] = x;}}}

test.c

#include "Sqlist.h"
void slinit()
{SL sl;
SLinit(&sl);//ctrl +d 快速复制//测试尾插
SLPushBack(&sl, 1); //因为是int类型,一开始空间是四个
SLPushBack(&sl, 2);
SLPushBack(&sl, 3);
SLPushBack(&sl, 4);
/*SLPushBack(&sl, 1);
SLPushBack(&sl, 1);*/
SLPrint(&sl);
//当传过去的是null空地址
//SLPushBack(NULL, 4); //传空地址乱码,要用accert判断
/*SLPushBack(&sl, 5);
SLPrint(&sl);*///测试头插
SLPushFront(&sl, 5);
SLPushFront(&sl, 6);
SLPushFront(&sl, 7);
SLPrint(&sl);//测试尾删
/*SLPopBack(&sl);
SLPopBack(&sl);
SLPopBack(&sl);
SLPrint(&sl);*///测试头删
SLPopFront(&sl);
SLPopFront(&sl);
SLPrint(&sl);
//测试指定位置插入
SLInsert(&sl, 0, 102);
SLInsert(&sl, 3, 15);
SLInsert(&sl, 4, 22);
SLPrint(&sl);//测试指定位置删除
SLErase(&sl, 0);
SLErase(&sl, 2);
SLPrint(&sl);//测试查找
SLFind(&sl, 2);//测试修改
SLAlter(&sl, 2, 3);
SLPrint(&sl);//测试销毁
SLDestroy(&sl);
SLPrint(&sl);
}
int main()
{slinit();return 0;
}

相关文章:

数据结构-顺序表详解专题

目录 顺序表 1.简单了解顺序表 2.顺序表的分类 2.1静态顺序表 2.2动态顺序表 2.3typedef命名作用 3.动态顺序表的实现 SeqList.h SeqList.c test.c 顺序表 1.简单了解顺序表 顺序表是线性表的一种&#xff0c;线性表是在逻辑上是线性结构&#xff0c;在物理逻辑上并…...

对商业知识和思维的一些小体会

用途&#xff1a;个人学习笔录&#xff0c;欢迎指正 前言&#xff1a; 小生拙见&#xff0c;我认为商业知识和商业思维的理解对于每一个行业都有潜在的帮助&#xff0c;因为每个人的生活都离不开商业&#xff0c;生意、工作都是交换&#xff0c;用自身提供的价值换取薪酬。因此…...

【笔记】计算文件夹的大小

目标&#xff1a;遍历文件夹&#xff0c;计算文件夹下包含文件和文件夹的大小。将这些结果存入python自带的数据库。 用大模型帮我设计并实现。 Step1 创建一个测试用的目录结构 创建目录结构如下所示&#xff1a; TestDirectory/ │ ├── EmptyFolder/ │ ├── SmallF…...

机器学习_常见算法比较模型效果(LR、KNN、SVM、NB、DT、RF、XGB、LGB、CAT)

文章目录 KNNSVM朴素贝叶斯决策树随机森林 KNN “近朱者赤&#xff0c;近墨者黑”可以说是 KNN 的工作原理。 整个计算过程分为三步&#xff1a; 计算待分类物体与其他物体之间的距离&#xff1b;统计距离最近的 K 个邻居&#xff1b;对于 K 个最近的邻居&#xff0c;它们属于…...

外包干了8个月,技术退步明显...

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…...

opencv#41 轮廓检测

轮廓概念介绍 通常我们使用二值化的图像进行轮廓检测&#xff0c;对轮廓以外到内进行数字命名&#xff0c;如下图&#xff0c;最外面的轮廓命名为0&#xff0c;向内部进行扩展&#xff0c;遇到黑色白色相交区域&#xff0c;就是一个新的轮廓&#xff0c;然后依次对轮廓进行编号…...

Websocket基本用法

1.Websocket介绍 WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手&#xff0c;两者之间就可以创建持久性的连接&#xff0c;并进行双向数据传输。 应用场景&#xff1a; 视频弹幕网页聊天体育实况更新股票基金…...

node.js与express.js创建项目以及连接数据库

搭建项目 一、技术准备 node版本&#xff1a;16.16.0 二、安装node成功后&#xff0c;安装express,命令如下&#xff1a; npm install -g express 或者&#xff1a; npm install --locationglobal express 再安装express的命令工具&#xff1a; npm install --location…...

【Tomcat与网络8】从源码看Tomcat的层次结构

在前面我们介绍了如何通过源码来启动Tomcat&#xff0c;本文我们就来看一下Tomcat是如何一步步启动的&#xff0c;以及在启动过程中&#xff0c;不同的组件是如何加载的。 一般&#xff0c;我们可以通过 Tomcat 的 /bin 目录下的脚本 startup.sh 来启动 Tomcat&#xff0c;如果…...

Java Agent Premain Agentmain

概念 premain是在jvm启动的时候类加载到虚拟机之前执行的 agentmain是可以在jvm启动后类已经加载到jvm中了&#xff0c;才去转换类。 这种方式会转换会有一些限制&#xff0c;比如不能增加或移除字段。 具体的做法,两者的实际做法是差不多的&#xff1a; premain 定义个静…...

Python实现设计模式-策略模式

策略模式是一种行为型设计模式&#xff0c;它定义了一系列算法或策略&#xff0c;并将它们封装成独立的类&#xff0c;使得它们可以相互替换&#xff0c;而不影响客户端的使用。 在策略模式中&#xff0c;算法或策略被封装在单独的策略类中&#xff0c;这些策略类实现了相同的…...

详解SpringCloud微服务技术栈:深入ElasticSearch(4)——ES集群

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;详解SpringCloud微服务技术栈&#xff1a;深入ElasticSearch&#xff08;3&#xff09;——数据同步&#xff08;酒店管理项目&a…...

AlmaLinux上安装Docker

AlmaLinux上安装Docker 文章目录 AlmaLinux上安装Docker一、前言二、具体步骤1、Docker 下载更新系统包索引&#xff1a;添加Docker仓库&#xff1a;安装Docker引擎&#xff1a; 2、Docker服务启动启动Docker服务&#xff1a;设置Docker开机自启&#xff1a; 3、Docker 安装验证…...

熟悉MATLAB 环境

一、问题描述 熟悉MATLAB 环境。 二、实验目的 了解Matlab 的主要功能&#xff0c;熟悉Matlab 命令窗口及文件管理&#xff0c;Matlab 帮助系统。掌握命令行的输入及编辑&#xff0c;用户目录及搜索路径的配置。了解Matlab 数据的特点&#xff0c;熟悉Matlab 变量的命名规则&a…...

【数据库数据恢复】Oracle数据库ASM磁盘组数据恢复案例

oracle数据库故障&分析&#xff1a; oracle数据库ASM磁盘组掉线&#xff0c;ASM实例不能挂载。数据库管理员尝试修复数据库&#xff0c;但是没有成功。 oracle数据库数据恢复过程&#xff1a; 1、将oracle数据库所涉及磁盘以只读方式备份。后续的数据分析和数据恢复操作都…...

STM32CubeMX教程31 USB_DEVICE - HID外设_模拟键盘或鼠标

目录 1、准备材料 2、实验目标 3、模拟鼠标实验流程 3.0、前提知识 3.1、CubeMX相关配置 3.1.0、工程基本配置 3.1.1、时钟树配置 3.1.2、外设参数配置 3.1.3、外设中断配置 3.2、生成代码 3.2.0、配置Project Manager页面 3.2.1、设初始化调用流程 3.2.2、外设中…...

知道Wi-Fi名称和密码之后自动连接

这里写自定义目录标题 有Wi-Fi名称和密码自动连接Wi-Fi主Activity服务类 WIFIStateReceiver工具类 WIFIConnectionManager 有Wi-Fi名称和密码自动连接Wi-Fi 主Activity public class MainActivity extends AppCompatActivity implements View.OnClickListener{private static…...

本地搭建Plex私人影音网站并结合内网穿透实现公网远程访问

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

【算法】拦截导弹(线性DP)

题目 某国为了防御敌国的导弹袭击&#xff0c;发展出一种导弹拦截系统。 但是这种导弹拦截系统有一个缺陷&#xff1a;虽然它的第一发炮弹能够到达任意的高度&#xff0c;但是以后每一发炮弹都不能高于前一发的高度。 某天&#xff0c;雷达捕捉到敌国的导弹来袭。 由于该系…...

记 doris 加载压缩文件(lzo、snappy)pr

做了一个case&#xff0c;是doris支持加载lzo压缩文件。[improvement](load) Enable lzo & Remove dependency on Markus F.X.J. Oberhumers lzo library by HowardQin Pull Request #30573 apache/doris (github.com) 其实doris里已经支持了 lzo&#xff0c;这个case源…...

2026第四届“盘古石杯“晋级赛 手机取证 手搓复盘(write up)

手机取证1. 分析黄志远phone.E01检材&#xff0c;黄志远手机总共安装了多少款短视频应用&#xff1f;[答案格式&#xff1a;1]apk 分析里面&#xff0c;4 个。当时把 b 站也算上了2. 分析黄志远phone.E01检材&#xff0c;黄志远手机安装的龙虾应用的包名是什么&#xff1f;[答案…...

taotoken token plan套餐详解如何节省大模型调用成本

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Taotoken Token Plan 套餐详解&#xff1a;如何节省大模型调用成本 对于频繁使用大模型 API 的企业开发者或个人用户而言&#xff…...

Path of Building完全汉化版PoeCharm:流放之路角色构建终极指南

Path of Building完全汉化版PoeCharm&#xff1a;流放之路角色构建终极指南 【免费下载链接】PoeCharm Path of Building Chinese version 项目地址: https://gitcode.com/gh_mirrors/po/PoeCharm 如果你是一名《流放之路》的玩家&#xff0c;是否曾经因为Path of Build…...

聚焦养老服务管理 以 AI 课堂革新实训教学模式

一、引言在养老产业数智化转型背景下&#xff0c;智慧健康养老服务与管理专业实训室建设需紧扣产业需求。AI 课堂作为教学数字化升级的核心载体&#xff0c;可有效破解传统实训教学与岗位需求脱节、高危场景难实操、教学评价不精准等痛点&#xff0c;为实训室建设提供实用可行的…...

从测试分类到缺陷管理

目录 1.多维测试分类&#xff1a;覆盖测试全场景 1.1 按测试目标分类 1.2 按执行方式分类 1.3 按测试方法分类 1.4 按测试阶段分类 1.5 按实施组织分类 2. 测试用例设计 2.1 用例设计万能公式 2.2 六大核心设计方法 3. 测试核心流程与 bug 管理 3.1 软件测试生命…...

二维紧束缚模型与量子电路映射技术详解

1. 二维紧束缚模型基础理论 紧束缚模型&#xff08;Tight-Binding Model&#xff09;是描述电子在周期性晶体场中运动行为的核心理论框架。这个模型的基本物理图像是&#xff1a;电子大部分时间被束缚在原子核附近&#xff0c;只有少量时间会隧穿到相邻原子轨道。在二维系统中&…...

从手机拍照到视频播放:一文看懂YUV(NV12/YUV444)格式为什么无处不在

从手机拍照到视频播放&#xff1a;YUV格式的技术演进与行业实践 当你用手机拍摄一张照片或录制一段视频时&#xff0c;图像数据在传感器采集后经历了一系列复杂的格式转换过程。这些转换不仅关乎图像质量&#xff0c;更直接影响着存储空间、处理速度和传输效率。在众多色彩编码…...

渗透测试授权书:法律效力与技术执行的耦合设计

1. 这份授权书不是“走个形式”&#xff0c;而是渗透测试合法性的生死线很多人第一次接触渗透测试&#xff0c;看到《渗透测试授权书》模板&#xff0c;第一反应是&#xff1a;“不就是签个字的事&#xff1f;网上随便找个PDF填上名字就行。”我2015年刚入行时也这么想&#xf…...

国产芯片独角兽IPO热潮来袭,百度昆仑芯与阿里平头哥角逐RISC-V弯道超车机遇

国产芯片好消息不断&#xff0c;长鑫科技与长江存储启动IPO&#xff0c;百度昆仑芯、阿里平头哥也有相关动作。互联网大厂钟情自研AI芯片&#xff0c;昆仑芯与平头哥发展路径不同&#xff0c;RISC-V或是弯道超车关键。国产芯片独角兽登场被誉为“存储双雄”的长鑫科技与长江存储…...

皮线、裸纤总是分不清?试试这个算法一键校准技巧

不知道你有没有经历过这种工地上的"崩溃瞬间"&#xff1a;大热天蹲在居民楼昏暗的楼道里&#xff0c;蚊子在耳边嗡嗡叫&#xff0c;你手里正拉着一根刚从住户门缝里拽出来的皮线光缆&#xff0c;准备跟分纤箱引出来的单模裸纤做熔接。结果放进机器&#xff0c;合上盖…...