【数据结构初阶】--顺序表(一)

【数据结构初阶】--顺序表(一)
🔥个人主页:@草莓熊Lotso

🎬作者简介:C++研发方向学习者

📖个人专栏: 《C语言》 《数据结构与算法》

⭐️人生格言:生活是默默的坚持,毅力是永久的享受。

前言:在上篇博客中我们学习了算法复杂度 ,明确了如何计算时间复杂度,能对写出来的代码进行一个评估,那么我们这篇博客将会给大家分享数据结构中顺序表的相关知识点。


目录

一.初识顺序表

1.1--线性表

1.2--顺序表的概念与结构

二.顺序表的分类

2.1--静态顺序表

2.2--动态顺序表 

三.动态顺序表的实现 --初始化

 seqlist.h:

 seqlist.c:

 test.c:

静态顺序表部分代码实现演示:(只包含.c文件和.h文件,测试文件这里就不写了)


一.初识顺序表

--在正式学习顺序表之前,我们先明确一下线性表这个概念

1.1--线性表

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

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

1.2--顺序表的概念与结构

--概念:顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况采用数组存储。

  • 逻辑结构:线性   
  • 物理结构:线性
顺序表和数组的区别:顺序表的底层结构是数组,对数组的封装,实现了常用的增删查改等结构 

 我们来举个例子对比一下数组和顺序表:(苍蝇馆子和米其林餐厅的对比)


二.顺序表的分类

2.1--静态顺序表

--使用定长数组存储元素

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

//静态顺序表
typedef int SLDataType;
#define N6
typedef struct Seqlist {
    SLDataType a[N];//定长数组
    int size;//有效数据个数
}SL;

 

2.2--动态顺序表 

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

//动态顺序表--按需申请

typedef struct Seqlist {
    SLDataType a[N];//定长数组
    int size;//有效数据个数

    intcapacity;//空间容量
}SL;

三.动态顺序表的实现 --初始化

--我们这里就分三个文件来实现一下动态顺序表,静态顺序表就不在这里演示了,但是博主会把静态顺序表的部分实现代码放在最后,大家可以自己看看。

 seqlist.h:

#pragma once #include<stdio.h> #include<stdlib.h> //定义顺序表的结构 typedef int SLTDataType; typedef struct Seqlist { SLTDataType* arr;//存储数据 int size;//有效数据个数 int capacity;//空间容量 }SL; //顺序表初始化 void SLInit(SL* ps); 
重要提示:

 


这里分别对int类型和顺序表进行了重名命,给int重命名是为了方便后续的修改,比如我想把一些用了SLTDataType的变量从int类型修改成char,只用在重命名这个地方修改就可以了。

然后是顺序表的重命名,这里将顺序表重命名为SL,后续使用起来更加方便,看起来也会更加清晰。重名命这一块知识点之前在结构体的博客中博主有更详细的讲述过,大家感兴趣的话可以点击下面的链接去看一看,结构体相关的知识点对于我们后续数据结构的学习来说还是蛮重要的。

【自定义类型-结构体】--结构体类型,结构体变量的创建和初始化,结构体内存对齐,结构体传参,结构体实现位段

 seqlist.c:

#define _CRT_SECURE_NO_WARNINGS #include"seqlist.h" void SLInit(SL* ps) { ps->arr = NULL; ps->size = 0; ps->capacity = 0; } 
重点提示: 

在这里先看看初始化就好了,至于尾插,头插等接口的实现会在后续的文章中讲解。这里的初始化很简单,也没有啥需要特别注意的。大家应该都可以看懂,就不展开来详细讲述了,补充一下这里对arr初始化的话大家可以直接malloc申请一块空间,但是我个人还是更喜欢这样写的,这样写之后该如何使用在下篇博客中会讲到的。

 test.c:

#define _CRT_SECURE_NO_WARNINGS #include"seqlist.h" void test1() { SL s1; SLInit(&s1); } int main() { test1(); return 0; }
重点提示:

我们这里传参数,一定要采用传址调用的形式,否则会出现一些错误(在这里会报未初始化的局部变量s1这个错误),因为传值调用修改形参并不影响实参,它们的地址终究还是不同的,而传址调用,形参的修改会影响实参,这里也可以参考之前我们在--指针超详解2中举的swap函数的例子,在那篇博客中我们对传址调用和传值调用讲述的更加详细。

【C语言指针超详解(二)】--const修饰指针变量,野指针的辩析,assert断言,指针的使用和传址调用



注意:除了部分情况外(数组名),有取地址操作符才叫做变量传地址。

我们编写代码最好勤测试,避免写出大量代码后再测试而导致出现问题,无法定位问题。大家可以想想,如果不经常性进行测试的话,等到后续程序写完后发现有问题,很难入手去解决,就算找到了错误,修改起来的工作量也还是蛮大的哈。而我们写一个板块进测试一下的话,可以及时找出问题并进行修正,所有测试这个习惯是一定需要具备的。

静态顺序表部分代码实现演示:(只包含.c文件和.h文件,测试文件这里就不写了)

1.SeqList.h

#pragma once #include<stdio.h> #include<string.h> #include <stdlib.h> #include <assert.h> // 增强程序可维护性 #define MAX_SIZE 10000 typedef int SQDataType; // 静态顺序表 // 问题:给少了不够用,给多了用不完浪费,不能灵活控制 typedef struct SeqList { SQDataType a[MAX_SIZE]; int size; }SL; //typedef struct SeqList SL; // 增删查改等接口函数 void SeqListInit(SL* ps); // 头插 尾插 头删 尾删 void SeqListPushBack(SL* ps, SQDataType x); void SeqListPushFront(SL* ps, SQDataType x); void SeqListPopBack(SL* ps); void SeqListPopFront(SL* ps); 

2.SeqList.c

#include "SeqList.h" //// 增删查改等接口函数 void SeqListInit(SL* ps) { memset(ps->a, 0, sizeof(SQDataType)*MAX_SIZE); ps->size = 0; } // 头插 尾插 头删 尾删 void SeqListPushBack(SL* ps, SQDataType x) { if (ps->size >= MAX_SIZE) { printf("SeqList is Full\n"); return; } ps->a[ps->size] = x; ps->size++; } void SeqListPushFront(SL* ps, SQDataType x); void SeqListPopBack(SL* ps); void SeqListPopFront(SL* ps); 

这里大家还可以看看静态顺序表尾插的实现,可以自己先尝试去理解一下,这样后续动态顺序表的尾插实现也能更好的入手哈。

小预告:到这里就把初始化部分给大家讲完了,由于初始化部分比较简单,就不把每一步拆开来讲了,大家通过我画的图应该就可以很好的理解掉这个部分,那么在下篇文章中博主将继续进行尾插,头插,头删,尾删等接口的实现,会拆开来详细讲述,让大家能更好的理解这几个接口实现的过程和需要注意的一些点。


往期回顾:

【数据结构初阶】--算法复杂度的深度解析

【C语言指针超详解(六)】--sizeof和strlen的对比,数组和指针笔试题解析,指针运算笔试题解析 

【C语言动态内存管理】--动态内存分配的意义,malloc和free,calloc和realloc,常见的动态内存的错误,动态内存经典笔试题分析,柔性数组,总结C/C++中程序内存区域划分 【自定义类型-结构体】--结构体类型,结构体变量的创建和初始化,结构体内存对齐,结构体传参,结构体实现位段

结语: 本篇文章就到此结束了,本篇博客是数据结构与算法专栏的第二篇,在下篇博客中会接着为大家分享顺序表中的其它知识点。大家感兴趣的话可以先看一下往期回顾中的几篇文章,都是对于数据结构来说比较重要的一些C语言知识储备,以及上一篇的算法复杂度,如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。

Read more

5分钟部署麦橘超然Flux,低显存设备也能玩转AI绘画

5分钟部署麦橘超然Flux,低显存设备也能玩转AI绘画 1. 为什么你值得花5分钟试试这个Flux控制台 你是不是也遇到过这些情况: * 想试试最新的Flux模型,但显卡只有8GB甚至6GB,一加载就报“CUDA out of memory”; * 下载完模型还要手动配置路径、改代码、调参数,折腾两小时还没看到一张图; * 网页版用着方便,但担心隐私泄露、生成被限速、图片被缓存; 别再纠结了——麦橘超然 - Flux 离线图像生成控制台,就是为这类真实场景而生的。它不是又一个需要编译、调参、查文档的实验项目,而是一个开箱即用的本地Web服务:模型已打包进镜像,float8量化技术让DiT主干网络显存占用直降近一半,Gradio界面简洁到连提示词输入框都标好了占位符,连SSH隧道怎么转发都给你写好了命令。 更重要的是,它真的能在你的旧笔记本、远程小内存服务器、甚至实验室里那台只配了RTX 3060的工位机上跑起来。本文不讲原理推导,不堆术语,就带你从零开始,5分钟内完成部署、打开浏览器、输入第一句描述、亲眼看到AI画出赛博朋克雨夜街道——所有操作一步接一步,复制粘贴就能

By Ne0inhk

简单易学的分离式部署小米智能家居Miloco方法

一、安装环境 * Windows用户:安装WSL2以及Docker * macOS/Linux用户:安装Docker 此处不再赘述,网上随便找个教程即可。特别地,对于Windows用户来说,你需要将 WSL2 的网络模式设置为 Mirrored。 二、使用Docker部署Miloco后端 以下均为bash命令。请Windows用户进入WSL2 / Linux、macOS用户进入终端操作: mkdir miloco cd milico vi docker-compose.yml 以下是compose的内容(不会使用vi的同学可以傻瓜式操作:先按i,再使用粘贴功能,然后按冒号,输入wq然后回车,记得关闭输入法): services:backend:container_name: miloco-backend image: ghcr.nju.edu.cn/xiaomi/miloco-backend:latest network_mode:

By Ne0inhk
无人机巡检系统 - 智慧交通基础设施监测 - 小目标/密集目标检测(如裂缝、垃圾) - 多类别路面病害联合检测 智慧交通高清无人机视角高速路面损害检测数据集

无人机巡检系统 - 智慧交通基础设施监测 - 小目标/密集目标检测(如裂缝、垃圾) - 多类别路面病害联合检测 智慧交通高清无人机视角高速路面损害检测数据集

航拍无人机视角高速路面损害检测数据集,3349张 yolo,voc,coco标注方式 图像尺寸:1152*2048 类别数量:6类 训练集图像数量:3153; 验证集图像数量:157; 测试集图像数量:39 类别名称: 每一类图像数 ,每一类标注数 Cracks - 裂缝:446, 815 Waterlogging - 积水:1208, 2091 Ravelling - 松散:459, 869 Muddy_road - 泥泞道路:952, 2084 Road_side_garbage - 道路旁垃圾:329, 429 Potholes - 坑洼:

By Ne0inhk
Flutter 三方库 modular_core 大型应用级鸿蒙微服务化架构适配解析:纵深拆解路由控制组件化隔离网格,利用轻量级依赖注入中枢斩断应用深层耦合羁绊-适配鸿蒙 HarmonyOS ohos

Flutter 三方库 modular_core 大型应用级鸿蒙微服务化架构适配解析:纵深拆解路由控制组件化隔离网格,利用轻量级依赖注入中枢斩断应用深层耦合羁绊-适配鸿蒙 HarmonyOS ohos

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 modular_core 大型应用级鸿蒙微服务化架构适配解析:纵深拆解路由控制组件化隔离网格,利用轻量级依赖注入中枢斩断应用深层耦合羁绊 在构建超大型、多业务线的鸿蒙应用时,代码的模块化分层与解耦是决定项目成败的关键。modular_core 作为 flutter_modular 的核心逻辑库,提供了一套纯粹的依赖注入(DI)和模块生命周期管理机制。本文将深入解析该库在 OpenHarmony 上的适配与应用实践。 前言 什么是 modular_core?它不是一个 UI 框架,而是一套管理“对象如何创建”和“模块如何组织”的底层协议。在鸿蒙操作系统这种强调模块化分发(HAP/HSP)和细粒度原子化服务的生态中,利用 modular_core 可以帮助开发者构建出高内聚、低耦合的系统底座。本文将指导你如何在鸿蒙端侧实现模块的动态注入与回收。 一、

By Ne0inhk