线性表 :: 顺序存储结构的实现

说明:本文属于读书笔记。笔者将以讲述的方式表达全片文章。故文中提到的某些字词是非正式术语,只是笔者本人的理解性词语。

线性表简介:想要了解点击此处

目录

  • 顺序存储结构简介
  • 顺序存储结构设计思路
  • 顺序存储结构设计的实现
  • 顺序存储结构功能的实现
    • 获取数据元素
    • 插入数据元素
    • 删除数据元素
  • 顺序存储结构的优缺点
  • 结语
    • 笔者对线性表顺序存储的观点
    • 关于性能
    • 其他

1. 顺序存储结构简介

1.1定义

用一段 地址连续的存储单元 依次存储线性表的数据元素。


1.2 实现基础

由于线性表中存储的是 同种数据类型 ,且存储单元连续,在 C 语言中,可以使用一维数据来实现顺序存储结构。


2. 顺序存储结构设计思路

当我们采取使用数组的方式来实现顺序存储结构是,势必要思考二者的异同。

首先,对于数组而言,其基本特点是 存储相同数据类型的数据存储单元的地址是连续的 ,最特殊的一点是:数组的起始索引位置为 0 ,这是一个切入点。比如说,如果我们设计的线性表希望他有记录数据个数的基本属性,同时希望存储的数据位置与其索引值相同,那数组中的 0 号位,是不是可以用来记录当前线性表的数据元素个数。(如下图)

其次,在我们定义了数组之后,数组大小与线性表数据元素个数有什么关系呢?
假设:我们定义了一个数组大小为20,那么由于 0 号位用于记录当前线性表的数据元素个数,故我们所设计的线性表最多可存储19个数据元素。即,线性表的最大存储数据元素应是 不超过 数组大小的。(与设计思路方式有关!)


3. 顺序存储结构设计的实现

如下代码:(设计方式:将顺序存储的数据元素个数作为内置属性,故使用结构体进行构造新结构。阅读者可仿照思路自行实现其他方式的设计。)

#define MAXSIZE 20               /* 为了后续需要改变数组大小而设定 */
typedef int ElementType;        /* 此处以 int 为例,后续可修改成其他任意数据类型 */
typedef struct{ElementType arr[MAXSIZE];    /* 数组,存储数据元素 */int length;                   /* 记录线性表当前元素个数 */
}LinkList;

4. 顺序存储结构功能的实现

函数 / 功能 实现思路(注意事项):

  1. 函数的是否需要返回值?如果需要放回置类型是什么?
  2. 是否需要传递参数?如果需要应该传递说明参数?
  3. 操作元素有哪些特殊情况?

4.1 获取数据元素
  1. 获取元素时,应考虑 LinkList 是否为空;
  2. 获取指定位置的元素时,应传入参数,且注意指定位置不能在数据索引范围之外。
void GetElement(LinkList L,int i,ElementType* val){// 情形一:传入的表为空if(0 == length)return;// 情形二:当输入的索引不在数组索引范围内,且小于 0 时,返回第一个元素if(i < 0)printf("%d\n",L[0]);// 情形三:当输入的索引大于当前线性表元素个数时,返回最后一个元素if(i > L.length)printf("%d\n",L[length]);// 排除情形后printf("%d\n",L[i-1]);
}

以上代码,笔者认为没必要这么"人性化",情形二和情形三,显然是应用者的输入失误,如果我们返回给他我们认为的值,如上述代码中的 L[0] 和 L[length] ,反而可能误导应用者,故修改上述代码如下:

void GetElement(LinkList L,int i,ElementType* val){if(0 == length || i < 0 || i > L.length)return printf("线性表为空或输入越界!\n");*val = L[i-1];printf("获取的目标值为:%d", *val);
}

4.2 插入数据元素

示意图:
由于是基于数组实现,当然避免不了数组本身的一些弊端。即当我们操作元素不在尾部时,数组的增删时间复杂度都在 O(n)。如果在第三个位置处插入一个新元素 111,则原数组从第三位到最后一位都得给这“新人”腾地方。如下图所示。腾地方也就算了,在实际过程中我们还受其他因素的影响。例如,如果没地儿腾怎么办?

  1. LinkList 是否已经满了,满则跳出。
  2. 插入位置是否合理,不合理则跳出;
  3. 如不存在上述情况,则执行腾地儿操作;
    注意实现方式:从末尾开始,指定位置后的元素均向后移动一位。由于输入的时位置标号,不是索引标号,故出现易错点。(自行推导,加深记忆和理解,如果只是想用代码,那就当个CV战士吧。)
  4. 将“新人”请到新位置;
  5. 计数增加。
void insertElement(LinkList* L,int i,ElemnetType val){if(MAXSIZE == L->length) {printf("线性表已满,无法插入。\n");return;}if(i < 0 || i > L->length+1)return;int k;if(i <= L->length){  /* 此时实现从末尾开始,指定位置后的元素均向后移动一位 */for(k = L->length-1;k >= i-1;k--)L->arr[k+1] = L->arr[k];}L->arr[i-1] = val;L->length++;
}

4. 3 删除数据元素

删除和插入的情形差不多,一个挪位置,一个填坑。

  1. LinkList 是否为空了,如果是空,则跳出。
  2. 删除位置是否合理,不合理则跳出;
  3. 如不存在上述情况,则执行填坑操作;
    注意实现方式:从末尾开始,指定位置后的元素均向前移动一位。
  4. 计数减少。
void deleteElement(LinkList* L,int i){if(0 == L->length) {printf("线性表为空,操作失败。\n");return;}if(i < 0 || i > L->length)return;int k;if(i < L->length){ /* 此时实现从末尾开始,指定位置后的元素均向前移动一位 */for(k = i;k < L->length;k++)L->arr[k-1] = L->arr[k];}L->length--;
}

5. 顺序存储结构的优缺点

5.1 优点
  1. 设定数组大小后(足够用),无需因为元素之间的逻辑关系而增加额外的存储空间。
  2. 可以快速的存取表中的元素。
5.2 缺点
  1. 插入和删除时,需要大量移动元素。

6. 结语

6.1 笔者对线性表顺序存储的观点
  1. 由于是基于数组实现的,线性表的顺序存储结构性能与数组性能大同小异。
  2. 由于设计的方式多种多样的,大家可以模仿着取实现其他形式的设计方案。如文中提到的用数组首元素存储当前线性表的大小的方案。
  3. 想必大家也能想到,文中没有说关于元素的访问修改等。为什么呢?因为基于数组。增删改查中,我们相对麻烦的就是增删,改和查十分简单就没必要实现。
  4. 在不同的编程语言中实现的底层方式不同。比如python中用序列实现等。
  5. 在此,还想给大家说明一点。学习数据结构重在理解设计思路,实现思路,遇到难以理解的,可以画图分析,这是一个很好的方法。在实际应用中,不要为了体现能力而使用(虽然本篇文章没有什么可体现能力的地方,大家懂意思就行)。能明白吗?因地制宜才是最佳选择。
6.2 关于性能

增:O(n)
删:O(n)
改:O(1)
查:O(1)

6.3 其他

有头单链表的设计与实现
无头单链表(待更新)
循环链表(待更新)
双向链表(待更新)

线性表 :: 顺序存储结构的实现相关推荐

  1. 第三章 线性表---顺序存储结构

    线性表(List):零个或多个数据元素的有限序列. 若将线性表记为(a1, ..., ai-1, ai , ai+1 , ..., an),则表中 ai-1 领先于ai , ai领先于ai+1,称ai ...

  2. 使用Java模拟线性表顺序存储结构

    在数据结构中,线性表分两种结构 顺序结构和链表结构 下面使用Java模拟一下顺序结构 主要难点在顺序结构的插入和删除 import java.util.ArrayList;//线性表顺序存储结构 pu ...

  3. 线性表定义 线性表顺序存储结构

    写在前面:本文章来自于在学习过程中的总结,供大家参考.因水平有限,博客中难免会有不足,恳请大佬们不吝赐教! 文章目录 线性表的定义 线性表的顺序存储结构 线性表顺序存储结构的优缺点 线性表的基本操作 ...

  4. 线性表顺序存储结构操作算法

    线性表顺序存储结构操作算法 ** 顺序表的初始化 线性表的插入算法 线性表的删除算法 线性表的查找算法** 根据书本的知识线性表顺序存储结构的操作算法其实是我们刚进入数据结构与算法的必修课 其实算法无 ...

  5. 线性表-顺序存储结构

    线性表-顺序存储结构 线性表基本概念: 线性结构的基本特征为: 集合中必存在唯一的一个"第一元素": 集合中必存在唯一的一个 "最后元素" : 除最后元素在外, ...

  6. 数据结构严蔚敏C语言版—线性表顺序存储结构(顺序表)C语言实现相关代码

    数据结构严蔚敏C语言版-线性表顺序存储结构(顺序表)C语言实现相关代码 1.运行环境 2.准备工作 1)项目构建 1>新建一个SeqList项目 2>新建两个文件Sources和Heade ...

  7. 数据结构线性表顺序存储结构和主要算法实现

    (1) 线性表的定义. 零个或多个数据元素的有限序列 序列线性表中有直接后继元素,有且仅有一个直接后继,有且仅有一个直接前驱,数据元素之间的关系是一对一的关系 常用的List操作: Operation ...

  8. 线性表顺序存储结构图书管理

    线性表顺序存储结构图书管理 一开始看书里面的线性表的顺序存储结构,感觉简单,觉得动态链表才能做出一点东西,但是顺序存储不仅于此,也能做出来.顺序结构相比链式结构,内容上有较大差异,各有难点 文章目录 ...

  9. 《数据结构与算法》——线性表顺序存储结构的插入与删除

    什么是线性表? 线性表是最基本.最简单.也是最常用的一种数据结构.线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列. 线性表中数据元素之间的关系是一对 ...

最新文章

  1. C++读写EXCEL文件方式比较 .
  2. mysql float 精度阶段_mysql下float类型使用一些误差详解
  3. 如何让 Mac在运行 Windows时享受极致体验?Parallels Desktop 16给你答案!
  4. OpenGL入门笔记(六)
  5. spark rdd map java_Spark map 遍历rdd中的每个元素
  6. Oracle内部错误ORA-07445[kpopfr()+339] [SIGFPE]一例
  7. 广东计算机科学导论考试试卷,计算机科学导论试题A答案
  8. java基于springboot+vue的旧物置换网站
  9. 智能小车寻迹c语言程序,智能小车循迹记时测速程序
  10. scala--模式匹配
  11. 通过路由器来设置局域网下无线打印机打印
  12. Java微信SDK方式进行网页授权
  13. java达内小发猫课程,详细说明
  14. vue 报错avoid mutating a prop directly since the value will be overwritten whenever
  15. Java_Java多线程_Java线程池核心参数 与 手动创建线程池
  16. jsp+servlet实现的简单登录验证
  17. java的图片上传详解
  18. Python字典嵌套
  19. Python turtle 绘制彩色蟒蛇(有注释)
  20. web前端工程师简历

热门文章

  1. 网站QQ扫码登录代码及详细说明
  2. markdown中编辑数学公式用到的技巧
  3. chunk-vendors.js 语法错误
  4. 关于显著性检验,有你想要的!
  5. PyTorch实现非极大值抑制(NMS)
  6. yolov5篇---官方代码docker部署训练
  7. 上传身份证百度ocr识别
  8. CSDN Markdown简明教程3-表格和公式
  9. 用C语言写一个 将从终端上接收到的8个一字节数据用3des加密之后再连接上随机生成的八个一字节的数据再发送给终端...
  10. CS0012 错误。必须添加对程序集”xxxxx,Version=4.0.0.0,Culture=neutral,PublicKeyToken=xxxxxxx“的引用