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

1.顺序表

数据结构-基础篇-顺序表

  • 带入主题
    • 1线性表及其实现方式
      • 1.1线性表
      • 1.2顺序表和链表
    • 2顺序表(动态和静态)
      • 2.1静态顺序表
      • 2.2动态顺序表
    • 3代码实现(贪吃蛇方式)
      • 3.1从哪开始呢
      • 3.2 初始化
      • 3.3 销毁
      • 3.4 插入
        • 3.4.1 前面插入
        • 3.4.2 尾插
      • 3.5 删除
      • 3.6 查找
        • 3.6.1 按位查找
        • 3.6.2 按值查找

带入主题

  • Q假设要实现一个贪吃蛇本体(不考虑渲染和食物产生),我该如何思考呢

  • A贪吃蛇是可改变方向线性数据不断增删产出的结果

那么我们便带入我们要学习的线性表

1线性表及其实现方式

你别蒙,我们讲顺序表怎么又冒出来个线性表,别管我们的大学计算机学的,线性表就是虚头八脑的定义,真正的实现就是顺序表和链表

1.1线性表

贪吃蛇都知道撒,有头有尾的,我们在电脑存储中如果按照顺序1 2 3 4 依次存储配上线性表就是顺序表,如果是按照链式(后续讲)排列配上线性表就是链表。

1.2顺序表和链表

简单来说顺序表就是小朋友排队,而链表就是在我的世界藏宝图加上宝箱中还有藏宝图,当找到一个数据后紧跟而来的就是下一个数据的地址。

  • 话不多说开始实操

2顺序表(动态和静态)

2.1静态顺序表

structSequenceList{intarr[10];intsize;};

静态顺序表就是用固定大小的静态数组来储存数据。长这样,你细想一下,他场景真的很局限,只适合你知道数组大小,此时有人就要说了,老师老师我知道柔性数组,:( ,那就是我们要讲的动态顺序表的范畴了。

2.2动态顺序表

  • 简单过一下 动态顺序表就是用一个堆上动态申请的数组来存储数据,如果空间不够可做扩容处理。
typedefintSqDateType;typedefstructSequenceList{SqDateType*arr;intsize;intcapacity;}SqList;
  • 上面先取一个昵称方便后续使用(打个比方你有天不想用int了你就想存char 你还能把所有int 改成car吗?)

  • size表示目前数据存储了多少,是水

  • 而capacity 就是瓶子 容量在那里 ,水快满的时候就要加大“容量”,有时候可以原地在杯子上面加个容器,但有时候被子上空间受限,只能另外找一个的杯子且上方空间不受限,把水灌到新杯子。

  • 而这个指针数组就是说的杯子的地址。

  • 而全程 你要记住,capacity与你申请的额外容器加上杯子本身永远同步,别觉得是废话

typedefintSqDataType;// 柔性数组版本(注意:没有 arr 指针)typedefstructSequenceList{intsize;// 当前元素个数intcapacity;// 当前容量SqDataType arr[];// 柔性数组,不占结构体大小}SqLis;
  • 柔性数组也类似,简单看看

3代码实现(贪吃蛇方式)

3.1从哪开始呢

  • 首先要有文件分装的思想,函数实现是一个文件,头文件肯定要有,在是主函数所在地,所以分为三个文件,最好要有意识让别人看到这个文件就知道是什么东西。

主函数

#include"SqList.h"intmain(){SqList s1;}

头文件

#pragmaonce#include<stdio.h>typedefintSqDataType;typedefstruct{SqDataType*arr;intsize;intcapacity;}SqList;

函数实现还没到

3.2 初始化

不管三七二十一先assert断言 防小人!!

  • malloc申请arr的地址 默认就申请四个刚刚取的昵称的大小
  • -把什么和什么同步来着,你知道的,杯子对吧
  • size制空
voidSqListInit(SqList*p){assert(p);p->arr=(SqDataType*)malloc(sizeof(SqDataType)*4);if(p->arr==NULL){printf("申请失败");return;}p->capacity=4;p->size=0;}

3.3 销毁

同样 assert !!

  • 由于是malloc动态开辟的内存所以需要手动free释放
  • 其他制空就行
voidSqListDestroy(SqList*p){assert(p);free(p->arr);p->arr=NULL;p->capacity=0;p->size=0;}

3.4 插入

首先干什么!!防小人!

他的声明是void SqListInsert(SqList* p, int i, SqDataType x);

别急,你看声明就知道,这个i啊万一小人会输一个特别大的值,我们没有怎么办,也就是没有折磨大的capacity,所以!! assert(i <= p->capacity);

  1. 顺着想哈,你要插入首先要空出位子,除了在尾部插入对吧,那就分类来看。
3.4.1 前面插入

用空位子,要从后往前,把最后一个往右后才能动最后一个减一的位子,否则会覆盖.

注意为什么size减一再赋值给j,因为size表示有几个数从一开始,而arr是从0开始的

3.4.2 尾插

尾部插入,不用移动位置,直接放在size上,因此我们知道了,其实两个可以合并。

voidSqListInsert(SqList*p,inti,SqDataType x){assert(p);assert(i>=0&&i<=p->size);intj=p->size-1;while(j>=i){p->arr[j+1]=p->arr[j];j--;}p->arr[i]=x;p->size++;}

聪明的你一定想到了,我们不是举了杯子的例子吗,扩容!!

  • 我们么此扩容扩成原来的1.5~2倍,他在未来会扩充的越来越慢,并且能尽量节省空间。我们再扩展一下就得到了。

扩容次数越来越少,分摊到每次插入上的平均成本(均摊时间复杂度)接近 O(1)

voidSqListInsert(SqList*p,invoidSqListInsert(SqList*p,inti,SqDataType x){assert(p);assert(i>=0&&i<=p->size);if(p->size==p->capacity){intnewcapacity=p->capacity*2;//为什么作者要在这里多此一举,如果capacity没有初始化呢,为0,那么不久完蛋了SqDataType*tmp=(SqDataType*)realloc(p->arr,sizeof(SqDataType)*(size_t)newcapacity);if(tmp==NULL){printf("realloc失败 \n");return;}p->arr=tmp;tmp=NULL;p->capacity*=2;}intj=p->size-1;while(j>=i){p->arr[j+1]=p->arr[j];j--;}p->arr[i]=x;p->size++;}

3.5 删除

原型是这个 SqDataType SqListDelete(SqList* ps, int i)

老规矩了,assert一定要断言

  • 然后就是删除主体了,删除后,你要让后续数据依次往前一位,插入和删除的时间复杂度为 O(n),需要移动大量数据,这是顺序表的主要短板,看看代码记得复刻哈。
SqDataTypeSqListDelete(SqList*p,inti){assert(p);assert(i>=0&&i<p->size);//保存数据留作返回值SqDataType dele=p->arr[i];for(intj=i;j<p->size-1;j++){p->arr[j]=p->arr[j+1];}--p->size;returndele;}
  • 注意为什么是 循环条件为 < size - 1 ,永远要有边界思想,假设size == 5有效值为 0 - 4 那么读取到5 就有问题。

3.6 查找

不要怕,顺序表太好查找了,暴力拆出来不就行了,一个是按位查找,一个是按值查找。

3.6.1 按位查找
SqDataTypeGetElem(SqList*ps,inti){assert(ps);assert(i>=0&&i<ps->size);returnps->arr[i];}
3.6.2 按值查找
intLocateElem(SqList*ps,SqDataType x){assert(ps);for(inti=0;i<ps->size;++i){if(ps->arr[i]==x)returni;}return-1;}

  • 因此我们的增删改查大多已经实现清楚了,我们从最开始贪吃蛇的引入(当然后续会出),到线性表底下两个分支,我们都大概交代了,顺序表基本实现和作者本人有些困惑的点也当作知识点分享了,下一期,我们讲重头戏——链表,做好准备了吗?
http://www.jsqmd.com/news/1040515/

相关文章:

  • 【C++】解构C++对象模型:你与“高手”之间,就差这篇类和对象-上
  • 从零开始:Visual Studio 2026 安装配置及第一个程序编写
  • 2026年五合一气体检测仪实力供应商选购参考汇总 - myqiye
  • 2026年6月自贡黄金回收市场六店走访全实测 - 余生黄金回收
  • PHP框架反序列化漏洞:从原理到实战深度剖析
  • 终极视频加速神器:Video Speed Controller完全指南
  • 基金投资入门
  • Ubuntu系统装机后初始化配置
  • Python开发中的常见陷阱与避坑策略
  • AI独角兽Odyssey融资3.1亿美元,黄仁勋、亚马逊、CIA都投了!世界模型赛道为何如此火爆?
  • 2026定制花束性价比高精品化红黑榜,真实横评,选定再拍不花冤枉钱 - mypinpai
  • 2026年6月自贡黄金回收门店实地探访全攻略 - 余生黄金回收
  • AD7612 ADC 采集驱动 FPGA 设计 Verilog Vivado
  • MCP6S91/2/3可编程增益放大器:原理、选型与STM32驱动实战
  • 2026年6月目前专业的船用阀门直销厂家怎么选择,船用铜铸件/船用附件/船用蝶阀/船用管系附件,船用阀门公司推荐 - 品牌推荐师
  • 2026年6月自贡黄金回收六大门店走访全记录 - 余生黄金回收
  • 第19期 电脑离线工具箱
  • 轻松掌握网络监控器1.28.4高级版,高效管理网络
  • DLSS Swapper:一键管理游戏DLSS版本,释放NVIDIA显卡全部潜力
  • MCUez Linker错误代码L1502-L1936全解析:从原理到实战解决链接问题
  • 2026瞬间胶厂商口碑推荐强势出炉,零套路不踩坑,选购看这篇就够 - mypinpai
  • Python入门学习6:Python 核心数据结构详解——集合(Set)与列表(List)
  • M2.7自反馈架构:大模型元认知能力的技术实现
  • Java技术总监(CTO/VP Engineering)面试全攻略:战略、组织与商业落地(2026实战版)
  • 2026协鼎教育咨询红黑榜 五大口碑机构深度解析避坑不踩雷 - mypinpai
  • NET环境使用PaddleSharp的入门Demo-控制台
  • 抖音视频批量下载终极指南:3分钟上手免费去水印工具
  • 你的下一个知己,何必是碳基生物?----猫娘计划「Project N.E.K.O.」
  • 2026年6月自贡黄金回收市场六店实测报告 - 余生黄金回收
  • 遵义黄金回收门店六家实测全记录与变现指南 - 余生黄金回收