-----------------------1、线性表基础操作------------------------

线性表:(List)由零个或多个数据元素组成的有限序列。

  • 首先他是一个序列,元素之间是有个先来后到的;
  • 若元素存在多个,则第一个元素无前驱,而最后一个元素无后继,其他元素都有且只有一个前驱和后继;(前一个元素是后一个元素的直接前驱,后一个元素是前一个元素的直接后继;)
  • 另外,线性表强调是有限的,事实上无论计算机发展到多强大,他所处理的元素都是有限的;
  • 所以线性表元素的个数n(n>=0)定义为线性表的长度,当n等于0时,称为空表。

抽象:是指抽取出事物具有的普遍性的本质。他要求抽出问题的特征而忽略非本质的细节,是对具体事物的一个概括,抽象是一种思考问题的方式,他隐藏了繁杂的细节。

线性表的抽象数据类型:(所谓抽象数据类型就是把数据类型和相关操作捆绑在一起,这就像我们面向对象这类高级语言的做法一样,把属性和方法捆绑在一块那就是类。)

我们对已有的数据类型进行抽象,就有了抽象数据类型(Abstract Data Type,ADT)是指一个数据类型及定义在该模型上的一组操作。(也可以自定义)

抽象数据类型的标准格式:

ADT 抽象数据类型名
Data数据元素之间逻辑关系的定义
Operation操作
endADT

线性表的相关操作:

  • 线性表的创建和初始化
  • 数据的删除和插入
  • 根据位序得到元素

线性表抽象数据类型的定义:

ADT 线性表(List)//他的名字叫做线性表有一个英文名字叫做List

Data//是什么数据呢?//下面具体描述数据的类型

线性表的数据对象集合为,每个元素的类型均为DataType。其中除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个an外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。
操作:

OperationInitList(*L):初始化操作,建立一个空的线性表L。ListEmpty(L):判断线性表是否为空表,若线性表为空,返回true ;否则返回false。ClearList(*L):将线性表清空。//就是把里边的数据都给清楚掉事实上呢就是把他们都填0,因为我们知道在内存中的数据不可能是真正的清除,他不能登一声就没有了,内存中一个位置总要放一个东西,你可以认为说0那时候就是一个空气啥都没有表示清空的意思。因为内存上的数据只能被覆盖。GetElem(L,I,*e):将线性表L中的第i个位置元素值返回给e。LocateElem(L,e):在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素在表中序号表示成功;否则,返回0表示失败。(注意:我们的数组是以0下标开始的,0就表示第一个元素;但是在线性表中是正常的思维,1就是1,2就是2,0就是没有的,所以返回0表示失败)ListInsert(*L,i,e):在线性表L中第i个位置插入新元素e。ListDelete(*L,i,*e):删除线性表L中第i个位置元素,并用e返回其值。ListLength(L):返回线性表L的元素个数。
endADT

对于不同的应用,线性表的基本操作是不同的,上述操作是最基本的,对于实际问题中涉及的关于线性表的更复杂的操作,完全可以用这些基本操作的组合来实现。

举例:比如想实现A和B的并集U。运用到的基本操作:

ListLength(L);//知道线性表的长度。

GetElem(L,i,*e);//获取元素。

LocateElem(L,e);//定位。

ListInsert(*L,i,e)//插入。

实现代码如下:

//La表示A集合,Lb表示b集合
void unionL(List *La,list Lb)//有两个线性表,为什么一个带指针,一个不带呢?
{int La_len,Lb_len,i;ElemType e;//声明和LaLb相同的元素e。La_len=ListLength(*La);//获取线性表长度。(因为我们传入的实参不同,所以我们的行参用指针和数据来表示而已。)Lb_len=ListLength(Lb);//接下来用一个迭代for(i-1;i<=Lb_len;i++)//(从1开始,因为线性表是给人看的所以从1开始(数据结构和算法是给人看的),给机器看的从0开始){GetElem(Lb,i,*e);//获取元素,(取Lb中第i个元素赋值给e)将线性表Lb第i个位置的元素值返回给e。if(!LocateElem(*La,e))//判断获取的元素在不在La里边//在线性表La中查找与给定值e相等的元素,如果查找成功,返回该元素在表中序号表示成功;否则,返回0表示失败。(ListInsert(La,++La_len,e);//如果不在呢就插入//在线性表La中第++La_len个位置插入新元素e。)//之后再进行第二次迭代}

------------------2、线性表的顺序存储结构----------------

线性表有两种物理存储结构:顺序存储结构和链式存储结构。

(1)线性表的顺序存储结构:指的是用一段地址连续的存储单元依次存储线性表的数据元素。(就像我们C语言中的数组)

a1 a2 a3 a4 ... ai-1 ai ai+1 ... an

物理上的存储方式事实上就是在内存中找个初始地址,然后通过占位的形式,把一定的内存空间给占位了,然后把相同数据类型的数据元素依次放在这块空地中。

线性表顺序存储的结构代码:

#define MAXSIZE 20//3定义下边数组的最大长度
typedef int ElemType;
Typedef struct
{ElemType data[MAXSIZE];// 2ElemType是一个类型,它可以时int,front等,在我们这里边上边我们用typedef定义为整形的int length;//线性表当前长度
}SqList;//4通过一个结构这个结构的名字叫做SqList对数组进行封装,多了一个length长度的变量。
//1这里封装了一个结构,事实上就是对数组进行了封装,增加了个当前长度的变量

总结:顺序存储结构封装需要三个属性

  • 顺序存储空间的起始位置,数组data,它的存储位置就是就是线性表存储空间的存储位置。
  • 线性表的最大存储容量:数组的长度Maxsize。
  • 线性表的当前长度:length。

PS:注意数组的长度与线性表的当前长度需要区分一下:数组的长度是存放线性表的存储空间的总长度,一般初始化后不变。而线性表的当前长度是线性表中元素的个数,是会变化的。

我们习惯了数组从下标0开始计算,但是线性表是从1开始计算的。假设ElemType占用的是c个存储单元(字节)(比如int占用4个字节),那么线性表中第i+1个数据元素和第i个数据元素的存储位置的关系是(LOC表示获得存储位置的函数):LOC(ai+1)=LOC(ai)+C(表示ai+1这个元素的地址相当于ai元素的地址+C(因为C是存储单元的宽度)),所以对于第i个数据元素ai的存储位置可以由a1存储推算出来:LOC(ai)=LOC(a1)+(i-1)*C。

------实现GetElem获取元素的具体操作,即将线性表L中第i个位置元素值返回,就程序而言非常简单如下,我们只需要把数组第i-1下标的值返回即可。

#define OK 1//这里用define OK表示1
#define ERROR 0
#define TRUE 1
#DEFINE FALSE 0typedef int Status;
//Status 是函数类型,其值是函数结果状态代码,如OK等。
//初始条件:顺序线性表L已存在,1<=i<=ListLength(L)
//操作结构:用e返回L中第i个数据元素的值。Status GetElem(SqList L,int i,ElemType *e)//有三个参数,第一个是线性表L;第二个是他的索引位置;第三个是他要返回的把他存放的再存放的一个值一个地址一个指针。
{if(L.length==0||i<1||i>L.length){return ERROR;//满足上述情况返回ERROR;}*e=L.data[i-1]; //其他情况下要把i-1这个下标的值把他放在e这个指针变量里边,那就可以了。return OK;//表示GetElem这个结果正确
} 

注意上述返回值类型Status是一个整型,约定返回1代表OK,返回0代表ERROR。

------实现ListInsert插入具体操作,ListInsert(*L,i,e)即在线性表L中的第i个位置插入新元素e。

插入算法的思路:

  1. 如果插入位置不合理,抛出异常;
  2. 如果线性表长度大于等于数组长度,则抛出异常或动态增加数组容量;
  3. 从最后一个元素开始向前遍历到第i个位置,分别将他们都向后移动一个位置。
  4. 将要插入元素填入位置i处;
  5. 线性表长+1。

实现代码如下:

//初始条件:顺序线性表L已经存在,1<=i<=ListLength(L)。
//操作结果:在L中第i个位置之前插入新的数据元素e,L长度+1。
Status ListInsert(SqList *L,int i,ElemType e)
{int k;if(L>length==MAXSIZE)//顺序线性表已经满了,放不进来了。{return ERROR;}if(i<1||i>L->length+1)//当i不在范围内时{return ERROR;} if(i<=L->length)//若插入数据位置不在表尾{//将要插入位置后的数据元素向后移动一位for(k=L->length-1;k>=i-1,k--){L->data[k+1]=L->data[k];//就是一个赋值的过程}  }L->data[i-1]=e;//将新元素插入,i-1是因为线性表i是从1开始的,数组是从0开始的。L->length++;return OK;
}

------实现ListDelete删除具体操作, ListDelete(*L,i,*e)即删除线性表L中第i个位置元素,并用e返回其值。

删除算法的思路:

  1. 如果删除位置不合理,抛出异常;
  2. 取出删除元素;(看一下怎么取的)
  3. 从删除位置元素开始遍历到最后一个元素位置,分别将他们都向前移动一个位置;
  4. 表长-1。
//初始条件:顺序线性表L已经存在,1<=i<=ListLength(L)。
//操作结果:删除L的第i个数据元素,并用e返回其删除的值,L的长度-1。
Status ListDelete(SqList *L,int i,ElemType *e)
{int k;if(L->length==0)//表长是否为空{return ERROR;//空表什么都没有,更不用说删除了。}if(i<1||i>L->length+1)//当i不在范围内时{return ERROR;} *e=L->data[i-1];//把他的值放到这个指针e里边去(因为上边定义的是一个指针变量)//因为是第i个元素,所以他的数组里边的索引就是i-1;if(i<=L->length)//只要i小于他的length,接下来就是移位{//将要删除位置后的数据元素向前移动一位for(k=i;k<L->length-1;k++){L->data[k-1]=L->data[k];//把删除位置后边的元素全部都向前移动//就是一个赋值的过程}  }L->length--;return OK;
}

数据结构和算法:(3)3.1线性表的顺序存储结构相关推荐

  1. 数据结构与算法:一、线性表的顺序存储结构SeqList和链式存储结构LinkList

    实现了线性表的链式存储结构和线性存储结构,能进行插入元素O(n),删除元素O(n),查找元素O(n)和返回线性表长度O(1)的操作.其中链式存储结构使用了C++11的智能指针进行内存管理. 要点:链式 ...

  2. 数据结构与算法(2-1)线性表之顺序存储(顺序表)

    顺序表用数组存储数据元素(可以是结构体数组,也可以是结构体内的元素数组),插入和删除等等也是类似数组的操作. 顺序表优势: 1.无须为表示表中元素之间的逻辑关系而增加额外的存储关系,就是直接的顺序: ...

  3. 数据结构与算法基础02:线性表

    目录 1. 线性表抽象数据类型 1.1 概述 1.2 抽象数据类型 2. 线性表的顺序表示和实现 2.1 概述 2.1.1 存储方式 2.1.2 逻辑关系表示 2.1.3 操作特性 2.2 实现 2. ...

  4. (二)《数据结构与算法》 青岛大学-王卓 线性表 C++

    <数据结构与算法> 青岛大学-王卓 线性表(链式存储)C++ B站链接:[https://www.bilibili.com/video/BV1nJ411V7bd?p=20] 本人能力有限, ...

  5. 《数据结构》c语言版学习笔记——线性表的顺序存储结构

    线性表的顺序存储结构 第一章 线性表的顺序存储结构 文章目录 线性表的顺序存储结构 前言 一.顺序存储结构的建立 1.条件 2.代码 二.顺序存储结构的获得元素 1.条件 2.代码 三.顺序存储结构的 ...

  6. 线性表之顺序存储结构相关算法学习

    作为一名准备干一辈子的程序员,学习算法还是很有必要的.所以从基础开始了.学习教材 是大话数据结构. 线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素.代码 参照教材 采用c ...

  7. 数据结构之线性表之顺序存储结构(3)

    1 前言 经过前两张的理论基础,我相信大家都能简单的明白了数据结构和算法一些常用的概念了,从今天开始我们开始学习数据结构中线性表,一起叩响数据结构的大门. 2 详述 线性表(List):零个或者多个数 ...

  8. 第三章 数据结构 线性表的逻辑结构 和 线性表的顺序存储结构,链式存储结构

    文章目录 线性表的特点 引用 集合与线性表的区别在于元素是否可以重复. 线性表的顺序存储结构 顺序存储的优缺点: 一维数组来表示顺序表的数据存储区域. 线性表的链式存储结构 链式存储的优缺点 线性表的 ...

  9. 【数据结构】之线性表(顺序存储结构)

    博主声明: 转载请在开头附加本文链接及作者信息,并标记为转载.本文由博主 威威喵 原创,请多支持与指教. 本文首发于此   博主:威威喵  |  博客主页:https://blog.csdn.net/ ...

最新文章

  1. GitHub 官方终于出 App 了!
  2. JS-排序详解:冒泡排序、选择排序和快速排序
  3. 人眼中亮斑的检测、定位和去除(2)
  4. linux下多路复用模型之Select模型
  5. 两种方式解决 生产者消费者问题
  6. 浅谈物联网时代智能停车发展趋势
  7. 使用shell脚本或命令行添加、删除 crontab 定时任务
  8. 用户行为分析笔记(二):系统的整体架构
  9. Linq------错误: Unable to determine the principal end of an association between the types
  10. 简述python在量化金融中应用_Python金融与量化投资分析应用
  11. node 升级_那些修改node_modules的骚操作
  12. IOS开发 ios7适配
  13. MATLAB智能算法
  14. NCCN指南下载以后无法复制,粘贴原因及PDF密码破解
  15. DP(Nietzsche)的hu测 T1(状压dp)
  16. 广告点击率预估是怎么回事?
  17. SpringMVC初学--hello world
  18. css 剪辑图片_css剪裁GIF背景图片动画特效
  19. 基于Docker的交互式人脸识别应用
  20. 山东大学软件工程期末复习知识点总结

热门文章

  1. 2021年大数据常用语言Scala(十三):基础语法学习 函数 重点掌握
  2. [C] 图的广度优先搜索——最少转机
  3. python raw_input 与 input 的区别
  4. .gitignore文件如何编写?
  5. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)
  6. 【PHP+JS】uploadify3.2 和 Ueditor 修改上传文件 大小!!
  7. [DevOps] 认识一下
  8. POJ 2430 状压DP
  9. docker4dotnet #4 使用Azure云存储构建高速 Docker registry
  10. displaytag 导出