前言

我们都知道,数据结构中逻辑结构可以划分为线性结构(线性表)与非线性结构两大类。

存储结构指的是数据元素在计算机中的存储及其逻辑关系的表现,也就是在计算机当中对逻辑结构的表示。

线性表的存储结构主要有顺序结构链式结构两种实现形式。本文主要探讨基于线性表的顺序结构也就是顺序表的四种基本操作:初始化插入删除查找

这些知识点既可能出现在选择题的考察当中又可以出现在编程大题当中,但是考察的侧重点不同,选择题重点关注操作的时间复杂度以及特性(特别是不同结构的顺序表,在实现某种操作时候的效率高低),编程大题只是关注代码实现能力。

基本知识分析

顺序存储 :

把线性表的结点按逻辑顺序依次存放在一组地址连续的存储单元里。用这种方法存储的线性表简称顺序表。(为了便于理解,大家可以近似得把这一段空间理解成一个C语言数组)

由于元素顺序排列,顺序存储具有以下性质和特征:

• 线性表的逻辑顺序与物理顺序一致;

• 数据元素之间的关系是以元素在计算机内“物理位置相邻”来体现

a1到an存放情况如图所示,设每个元素占l个单元长度。(ps:计算机中数组下标实际从0开始)

ai的地址:Loc(ai)=Loc(a1)+(i-1)×1

因此顺序表的结构体当中应当包含 一块连续的地址空间当前存放元素的长度当前分配的存储容量。由此写出结构体如下:

typedef struct{
ElemType *elem;//存储空间基址
int length;//当前长度
int listsize;//当前分配的存储容量
}SqList;

在了解顺序表静态构造的基础上,我们可以在这个基础上构建它的几个基本操作了。

1

初始化

输入:MAXSIZE,表示要申请MAXSIZE个元素大小的地址单元。

关键代码:

L->elem=(ElemType *)malloc(MAX_SIZE*sizeof( ElemType));//分配空间
L->length=0;//空表长度为0
L->listsize=MAX_SIZE;//初始存储容量

2

插入

设n个元素存放在elem[0...length-1]内。

输入:i,e,表示要在下标为i处插入值为e的元素。

分析插入过程导致的结果:元素数量从length变成了length+1,如果只是简单地将下标为i处的元素替换成e,会导致原先的元素丢失。因此插入操作可以表述为:(1)将该元素以及该元素之后的所有元素都向后移动一个位。(2)元素大小加1。(3)再将e写入到下标为i处。比如对于[1,2]这个数组来说,将0插入到第一位,事实上是先使得第一位以及第一位之后的所有元素后移一位,数组变成[1,1,2],然后将0写入第一位,数组变成[0,1,2]

关键代码:

//elem[i...length-1]向后移动for(j = length-1; j >= i; j--){
L->elem[j+1] = L->elem[j]
}//元素大小加1
length++;//e写入下标为i处
L->elem[i]=e;

3

删除

设n个元素存放在elem[0...length-1]内。

输入:i,表示要删除下标为i处的元素。

分析删除过程导致的结果:元素数量从length变成了length-1,如果只是简单地将下标为i处的元素被删除,会导致此处出现一个空白单元。因此删除操作可以表述为:(1)将该元素之后的所有元素都向前移动一个位。(2)元素大小减1。将i+1处的元素移动到i处时完成了覆盖,事实上等同于删除了i处的元素。比如对于[0,1,2]这个数组来说,将第二个元素移动到第一个,第三个元素移动到第二个也就是数组变成了[1,2,2],但是此时length=2说明数组长度为2,取前2个元素,事实上完成了对0的删除。

关键代码:

//elem[i+1...length-1]向前移动for(j = length-1; j > i; j--){
L->elem[j-1] = L->elem[j]
}//元素大小减1
length--;

4

查找

设n个元素存放在elem[0...length-1]内。

输入:e,表示查找值为e的元素。

输出:i,表示值为e的元素位于下标为i处,若查找不成功,i=-1(或者自己定义其他不属于0...length-1的值)

分析查找过程:其实是从头到尾遍历每一个元素,比较当前元素是否等于查找值e,若等于则返回下标i,当遍历完毕n个元素还是没有返回值,说明表中不存在要查询的元素。

关键代码:

//遍历比较每一个元素for(i=0; i < length; i++){if(EQ(L->elem[i], e)){ return i;}
}//遍历结束没有返回值,说明不存在return -1;

选择题角度

重点考察 时间复杂度特性以及执行相关操作的效率

根据前面的分析以及关键代码部分可以观察到:

1

初始化

关键代码只涉及到一次堆分配malloc以及修改listsize和length,频度为3,时间复杂度为O(1)

2

插入

关键代码分为三步:(1)修改length,频度为1,时间复杂度为O(1);(2)elem[i...n-1]向后移动,移动n-i次,频度为n-i,时间复杂度为O(n);(3)向下标为i处写入元素e,频度为1,时间复杂度为O(1)。综上总的时间复杂度为O(n)

3

删除

关键代码分为两步:(1)修改length,频度为1,时间复杂度为O(1);(2)elem[i+1...n-1]向前移动,移动n-i-1次,频度为n-i-1,时间复杂度为O(n)。综上总的时间复杂度为O(n)

4

查找

关键代码:遍历整个序列比较是否有元素的值为e,遍历结束时查找不成功则返回-1。显然若第一个元素就是要找的元素时,只比较一次,若最后一个元素是要找的元素则比较n次,若不存在该元素同样是比较n次,比较次数的取值范围为1到n,若每个元素出现频率相等,查找成功的情况下平均比较次数为(n+1)/2次,时间复杂度为O(n)

综上,在顺序表中,访问下标为i的元素可以通过 随机访问 ,如elem[i]获取,时间复杂度为O(1),但是对于插入和删除这样的动态操作时间复杂度都为O(n),顺序查找时间复杂度也为O(n)。

编程角度

一个完整的操作函数,是由 健壮性保证 以及 关键代码 两部分组成的。

1

初始化

malloc可能会有分配失败的可能,因此要对此进行判断。

bool InitList(SqList *L){
L->elem=(ElemType *)malloc(MAX_SIZE*sizeof( ElemType));//分配空间if(!L->elem){ return false;}//基址指针为空时分配失败
L->length=0;//空表长度为0
L->listsize=MAX_SIZE;//初始存储容量return true;
}

2

插入

• 对于elem[0...length-1]来说合法的插入范围应该是0~length,要对输入的i进行判断。

• 插入会使得表长加1,可能会发生上溢,也就是分配空间不够,所以要对此进行判断。

bool ListInsert(SqList *L, int i, ElemType e){int j;if(i < 0 || i > L->length) { return false;}//i输入是否合法if(L->length >= L->listsize){
 newbase = (ElemType *)realloc(L->elem, (L->listsize + INCREMENT)*sizeof( ElemType));//分配空间if(!newbase){return false;}//分配失败
 L->elem = newbase;
 L->listsize += INCREMENT;
}//是否上溢//elem[i...n-1]向后移动for(j = L->length-1; j >= i; j--){
 L->elem[j+1] = L->elem[j]
}//元素大小加1
L->length++;//e写入下标为i处
L->elem[i]=e;return true;
}

3

删除

• 对于elem[0...length-1]来说合法的删除范围应该是0~length-1,要对输入的i进行判断。

bool ListDelete(SqList *L, int i, ElemType &e){if(i < 0 || i > L->length - 1){ retrun false;}//i输入是否合法
e = *(&L->elem[i]);//elem[i+1...length-1]向前移动for(j = L->length-1; j > i; j--){
 L->elem[j-1] = L->elem[j]
}//元素大小减1
L->length--;return true;
}

4

查找

int Locate(SqList* L, ElemType e){int i;//遍历比较每一个元素for(i=0; i < L.length; i++){if(EQ(L->elem[i], e)){ return i;}
}//遍历结束没有返回值,说明不存在return -1;
}

以上就是学长给大家归纳的关于线性表的相关基本操作了。

这里大牛学长帮大家最后总结一下。

⭕ 对于增、删、查、改几个基本操作,由于顺序表元素存在于一片连续空间。每一次做遍历相关操作的时候,都需要用一个全局的for循环去近似遍历整个表,因此这几个操作的时间复杂度都是O(n),即线性的。

⭕ 对于增、删操作,一定要做好合法性判断,在编程大题中,合法性判断是判卷老师对于学生编程素质的重点考察点,你不能说老师一定会关注合法性判断,但是写上合法性判断相关的代码一定会为你加上一点“印象分”!

今天是2020年8月18日

距离2021考研还有 122 天  

全力以赴,才有资格说尽力。

大牛学长一直在~

数据结构知识点总结_大牛带你学 | 考研数据结构中线性表中顺序结构的知识点总结...相关推荐

  1. java已知一个二叉树_大牛带你学 | 由二叉树的遍历序列求二叉树结构的解题方法归纳...

    前言 二叉树章节 属于数据结构考察的三大重点章节(线性表.树.图)之一,不管是在自命题院校考察和408统考都是考察频次很高的考点.今天,大牛学长就来为各位同学总结归纳一个二叉树知识考察中的常见题型的解 ...

  2. 南京邮电大学计算机数据结构考研真题,南京邮电大学考研数据结构真题.pdf

    南京邮电大学考研数据结构真题 状元 南京邮电大学99-06 年硕士研究生入学考试数据结构试题 第 1 页 共 15 页 状元 南京邮电大学99-06 年硕士研究生入学考试数据结构试题 第 2 页 共 ...

  3. 关于主机的思维导图_「停课不停学」思维导图—初中语文全部知识点总结,高清可打印...

    导读 思维导图的创始人东尼·博赞先生在读大学的时候,作为一名大一新生,在第一天上课时,好奇心就被略带傲慢的教授点燃了,因为他之前从来没见一个老师可以不用翻花名册点名,而且是第一次上课,全部是新生的情况 ...

  4. 大牛带你学优化~案例进阶Mysql优化

    在进行 MySQL 的优化之前必须要了解的就是 MySQL 的查询过程,很多的查询优化工作实际上就是遵循一些原则让 MySQL 的优化器能够按照预想的合理方式运行而已. MySQL 查询过程 优化的哲 ...

  5. 多线程导出excel高并发_大牛带你深入java多线程与高并发:JMH与Disruptor,确定能学会?...

    前言 今天我们讲两个内容,第一个是JMH,第二个是Disruptor.这两个内容是给大家做更进一步的这种多线程和高并发的一些专业上的处理.生产环境之中我们很可能不自己定义消息队列,而是使用 Disru ...

  6. 广联达2018模板算量步骤_老师傅带你学造价,广联达GTJ2018图文详解,小白也能学会的软件...

    在GTJ2018问世之前,土建造价人员有三个软件是必会的,一个是GGJ主打钢筋算量,一个是GCL主打土建算量,还有一个是GBQ主要是套定额用来计价的软件. 那时候如果计算一个工程的工程量,首先要用GG ...

  7. python讲1020逆序输出_手把手带你学 Python3(九)| 快速实现数据处理的不二工具(文末有彩蛋)...

    ", line 1, in TypeError: 'int' object is not callable #当然实际代码绝对不能这么写,这里是为了说明函数名也是变量.要恢复abs函数,请重 ...

  8. 分组聚合显示全部列_小胖带你学SQL(三)聚合与排序

    1 对表进行聚合查询 1.1 聚合函数 函数用来在SQL中对数据进行某种操作和计算. 以下是常用的5种函数: COUNT: 计算表中的记录数(行数) SUM: 计算表中数值列中数据的合计值 AVG: ...

  9. python数据抓取技术与实战训练_师傅带徒弟学Python:项目实战1:网络爬虫与抓取股票数据...

    本视频基于**Python 3.X版本 本视频课程是第四篇第一个实战项目,内容包括网络爬虫技术.使用urllib爬取数据.使用Selenium爬取数据.使用正则表达式.使用BeautifulSoup库 ...

最新文章

  1. 用计算机制作演示文稿教案博客,制作演示文稿 教学反思
  2. 使用个推的时候出现Installation error: INSTALL_FAILED_DUPLICATE_PERMISSION
  3. 【Java报错】MultipartFile 类型文件上传 Current request is not a multipart request 问题处理(postman添加MultipartFile)
  4. PPO-强化学习算法
  5. 不同编程语言能耗不同?看这27种语言对比!
  6. 【代码笔记】iOS-翻书效果的实现
  7. 你羡慕了吗?10万个数字人民币红包派发,每个200元
  8. CString转换为char*
  9. AtCoder Beginner Contest 185
  10. viewport原理和使用和设置移动端自适应的方法(移动适应电脑)
  11. alisql mysql_alisql安装步骤
  12. 计算机组成原理试题解析答案,计算机组成原理习题答案解析(蒋本珊)
  13. 数学作图工具_分别用于教学、排版、科研的数学作图软件
  14. 企业邮箱哪个品牌最好用?10年hr的经验分享
  15. 亲影:您的相册需要一个专属管家
  16. 业务流程管理工具的概览和比较分析
  17. 大数据高级开发工程师——Spark学习笔记(6)
  18. 组合数学——特征方程与线性递推方程
  19. 秒杀系统-商品详细页多级缓存实战(一)
  20. linux账号安全管理,保证Linux系统安全——帐号管理

热门文章

  1. php中队列控制的方法,学习猿地-php 队列的实现方法
  2. java 获取ip地址_老杜带你学Java【第二课】
  3. R语言对数线性模型loglm函数_R 对数变换 《回归分析与线性统计模型》page103
  4. 数据库mysql中贴换函数_关于一个自定义MYSQL函数,实现点击链接后,在数据库里改变数据的问题。...
  5. qt下QString转换为const char*字符串
  6. qt解决循环创建的控件,每个都绑定相同的槽函数时出现的一对多响应问题
  7. C语言 __LINE__ - C语言零基础入门教程
  8. BugkuCTF-Crypto题affine
  9. idea创建java项目目录结构_用IDEA创建一个简单的Maven的JavaWeb项目
  10. 手机访问服务器中的数据库文件,手机连接服务器数据库文件在哪里