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

zfk_蓝桥杯C++学习_语言基础_线性表及顺序表

一、线性表

1.定义: 由n(n≥0)个数据特性相同的元素构成的有限序列,称为线性表。

2.线性表的特点:
线性表是n个数据元素的有限序列,其中n个数据是相同数据类型的。

线性表中元素的个数n(n≥0)定义为线性表的长度,当n=0时称之为空表。

对于非空的线性表或线性结构,其特点是:
(1)存在唯一的一个被称作“第一个”的数据元素;
(2)存在唯一的一个被称作“最后一个”的数据元素;
(3)除第一个元素外,结构中的每个数据元素均只有一个前驱;
(4)除最后一个元素外,结构中的每个数据元素均只有一个后继。

3.线性表 ADT

ADT List 
{数据对象:D={ailai∈ ElemSet,i=1,2, ... ,n,n≥0}数据关系:S={<ai-1,ai>|ai-1,ai ∈ D, i=2, ... ,n}基本操作:InitList (&L)操作结果:构造一个空的线性表L。DestroyList (&L)初始条件:线性表L已存在。操作结果:销毁线性表L。
} ADT List

二、顺序表

1.定义: 用一组连续的内存单元依次存储线性表的各个元素,也就是说,逻辑上相邻的元素,实际的物理存储空间也是连续的。

2.基本操作:

(1)顺序表-初始化

#define MAXSIZE 100
typedef int ElemType;typedef struct
{ElemType data [MAXSIZE];int length;
} SeqList;void initList (SeqList *L)
{L->length = 0;
}

(2)顺序表-在尾部添加元素

int appendElem(SeqList *L, ElemType e)
{if (L->length>=MAXSIZE){printf("顺序表已满\n");return 0;}L->data[L->length] = e;L->length++;return 1;
}

(3)顺序表-插入元素

int insertElem(SeqList *L, int pos, ElemType e)
{if (pos <= L->length){for (int i = L->length-1; i >= pos-1; i -- ){L->data[i+1] = L->data[i];}L->data[pos-1] = e;L->length++;}return 1;
}

(4)顺序表-删除元素

int deleteElem(SeqList *L, int pos, ElemType *e)
{*e = L->data [pos-1] ;if (pos < L->length){for (int i = pos; i < L->length; i++){L->data[i-1] = L->data[i];}}L->length --;return 1;
}

(5)顺序表-遍历

void listElem (SeqList *L)
{for (int i = 0; i < L->length; i++){printf("%d ", L->data[i]) ;}printf("\n");
}

(6)顺序表-查找

int findElem(SeqList *L, ElemType e)
{for (int i = 0; i < L->length; i++){if (L->data[i] == e){return i + 1;}}return 0;
}

(7)顺序表-动态分配内存地址初始化

typedef struct
{ElemType *data;int length;
} SeqList;SeqList* initList ()
{SeqList *L = (SeqList*)malloc(sizeof(SeqList));L->data = (ElemType*) malloc(sizeof (ElemType)*MAXSIZE);L->length = 0;return L;
}

3.缺点:
顺序表作为基于连续内存空间的数据结构,不管是静态还是动态实现方式,都存在插入删除效率低、扩容有额外开销等缺点。

(1)插入与删除操作效率低:顺序表要保持元素的连续存储特性,当在表头或表中间位置执行插入操作时,得把目标位置及之后的所有元素依次后移,才能腾出空间;删除这类位置的元素时,又要把删除位置之后的元素依次前移来填补空缺。这些操作都要移动大量元素,时间复杂度为 O (n),数据量越大,操作耗时越明显。例如在有 1000 个元素的顺序表第 10 位插入元素,就需要移动后续 991 个元素。

(2)扩容操作存在额外开销:静态顺序表的大小固定,一旦元素数量达到预设上限就无法继续插入;动态顺序表虽可扩容,但过程繁琐。通常要先申请一块更大的新内存,接着将旧空间中的所有数据复制到新空间,最后释放旧空间。而且若扩容策略不合理,比如每次只扩容 1 个单位,插入 n 个元素可能产生 O (n²) 的时间成本;即便采用翻倍扩容的推荐策略,扩容时的数据拷贝操作依旧会带来短暂的性能损耗。

(3)空间利用率不佳:静态顺序表容易出现空间浪费或不足的问题,预设空间过大,多余部分会闲置;预设过小又会提前达到存储上限,无法新增元素。动态顺序表也有缺陷,扩容后若后续删除了大量元素,多出来的空闲空间往往不能自动释放,只能手动处理(部分编程语言),这就造成了内存的无效占用。比如动态顺序表扩容到 200 个存储单元后,若元素减少到 50 个,剩余 150 个单元的空间就被浪费了。

(4)依赖连续内存空间:顺序表需要一块完整连续的内存区域存储数据。当数据量较大时,系统中可能难以找到适配的连续内存块,即便此时系统整体剩余内存总量足够,也无法满足顺序表的存储需求,从而限制了其存储大规模数据的灵活性。

(5)易引发内存相关问题:在 C/C++ 等需要手动管理内存的语言中,动态顺序表若使用后忘记释放内存,会造成内存泄漏;同时扩容后旧空间若释放不当,还可能产生内存碎片。这些问题不仅浪费系统资源,还可能导致程序运行异常,增加了开发中的内存管理难度。

http://www.jsqmd.com/news/101521/

相关文章:

  • 当InfluxDB还在“散步”,金仓数据库已经“起飞”了!——一次不太公平的时序对决实录
  • 动态IP的使用方法
  • TradingView图表库K线生成机制深度解析与实战指南
  • LobeChat求职信撰写辅助系统
  • NBA 球员交易解禁有啥规则?看保罗的情况就懂了!
  • 智能字体协作者:AutoCAD字体自动修复的终极解决方案
  • 字符设备驱动(5)
  • 项目计划如何制定才靠谱?WBS、甘特图、里程碑一次讲清
  • 鸣潮自动化工具:新手也能轻松掌握的3大核心功能详解
  • LoRA微调概论
  • 永磁同步电机无位置传感器控制:龙伯格(Luenberger)观测器与Simulink模型
  • 零刻预告全球最小双盘位NAS:Intel、AMD、Arm随便选
  • C# 排序,字典以及类相关知识点扩宽
  • Daily Prob 5
  • Applite:终极Mac软件管理神器,让Homebrew图形化操作如此简单
  • 阿里云渠道商:轻量服务器远程协作性能优化指南
  • 如何实现 “右移”的智能监控,快速定位和恢复线上事故?
  • 我发现图神经网络补全罕见病知识图谱基层漏诊率骤降
  • 在React Native中实现鸿蒙跨平台开发分享功能,你可以使用`react-native-share`库,这个库支持多种分享方式,包括文本分享、图片分享,甚至是文件分享
  • BetterNCM插件完整使用指南:从入门到精通的网易云音乐体验升级
  • 终极指南:如何用wps-view-vue轻松实现WPS文档在线预览功能
  • 大模型薪资揭秘:百万年薪是主流,千万年薪是特例,收藏这份务实指南
  • 在一个事务里面死循环select一条数据,当我开启事务时,数据是1,每过5秒我就select一次,这个时候mybatis的一级缓存起作用了,所以不会去数据库查数据,等别的线程更新了数据表的数据,会使m
  • 在DevSecOps中,如何将安全测试(SAST/DAST等) 无缝集成到CI/CD流水线?
  • 3分钟掌握AI视频字幕去除:开源神器video-subtitle-remover完全解析
  • AI大模型落地指南:十大行业案例详解,程序员必收藏
  • 元胞自动机Python康威生命游戏
  • 四步重塑小米AI音箱:从语音助手到全屋智能中枢的进化之路
  • Set和Get访问器and构造函数(析构函数)
  • 婚礼誓词撰写:LobeChat见证幸福时刻