零个或多个数据元素的有限序列 。
线性表,从名字上你就能感觉到,是具有像线一样的性质的表。在广场上,有很多人分散在各处,当中有些是小朋友,可也有很多大人,甚至还有不少宠物,这些小朋友的数据对于整个广场人群来说,不能算是线性表的结构 。 但如果一个班级的小朋友,一个跟着一个排着队,有一个打头,有一个收尾,当中的小朋友每一个都知道他前面一个是谁,他后面一个是谁,这样如同有一根线把他们串联起来了 。 就可以称之为线性表 。
线性表(List):有零个或多个数据元素的有限序列 。
①首先它是一个序列 。 也就是说,元素之间是有顺序的,若元素存在多个,则第一个元素无前驱,最后一个元素无后继,其他每个元素都有且只有一个前驱和后继 。 如果一个小朋友去拉两个小朋友后面的衣服,那就不可以排成 一 队了;同样,如果一 个小朋友后面的衣服,被两个甚至多个小朋友拉址,这其实是在打架,而不是有序排队。
②然后,线性表强调是有限的,小朋友班级人数是有限的,元素个数当然也是有限的。事实上,在计算机中处理的对象都是有限的,那种无限的数列,只存在于数学的概念申。
如果用数学语言来进行定义 。 可如下 :
若将线性表记为 (a1 ,…,ai-1 , ai, ai+1 ,…, an) ,则表中 ai-1 领先于 ai, ai领先于 ai+1,吨,称 ai-1 是 ai的直接前驱元素, ai+1是a的直接后继元素。如图:
所以线性表元素的个数 n(n>0)定义为线性表的长度,当 n=0 时,称为空表 。
在非空表中的每个数据元素都有一个确定的位置,如 a1是第一个数据元素, an 是最后一个数据元素,ai是第 i 个数据元素,称 i 为数据元素 a在线性表中的位序 。
在较复杂的线性表中 , 一个数据元素可以由若干个数据项组成。
线性表的抽象数据类型定义如下:
对于不同的应用,线性表的基本操作是不同的,上述操作是最基本的,对于实际问题中涉及的关于线性表的更复杂操作,完全可以用这些基本操作的 组合来实现 。
比如,要实现两个线性表集合 A 和 B 的并集操作 。即要使得集合 A=A U B 。 说 白了,就是把存在集合 B 中但并不存在 A 中的数据元素插入到 A 中即可 。
我们假设 La 表示集合 A , Lb 表示集合 B ,则实现的代码如下:
3.1顺序存储定义
说这么多的线性表,我们来看看线性表的两种物理结构的第一种一一顺序存储结构。
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素 。
线性表( 旬a1,a2, … ,an ) 的顺序存储示意图如下:
3.2顺序存储方式
线性表的顺序存储结构说白了,和刚才的例子 一样,就是在内存中找了块地儿,通过占位的形式,把一定内存空间结占 了, 然后把相同数据类型的数据元素依次存放在这块空地中。既然线性表的每个数据元素的类型都相同,所以可以用 C 语言(其他语言也相同)的一维数组来实现顺序存储结构, 即把第一个数据元素存到数组下标为 0 的位置中,接着把线性表相邻的元素存储在数组中相邻的位置 。
线性表的顺序存储的结构代码:
这里,我们就发现描述顺序存储结构需要三个属性:
• 存储空间的起始位置:数组 date ,它的存储位置就是存储空间的存储位置。
• 线性表的最大存储容量 : 数组长度 MaxSize 。
• 线性表的当前长度 : length .
3.3数据长度与线性表长度区别
数组的长度是存放线性表的存储空间的长度,存储分配后这个量是一般是不变的。
线性表的长度是线性表中数据元素的个数,随着线性表插入和删除操作的进行,这个量是变化的。
3.4地址计算方法
由于我们数数都是从 1 开始数的,线性表的定义也不能兔俗,起始也是 1 , 可 C语言中的数组却是从 0 开始第一个下标的,于是线性表的第 i 个元素是要存储在数组下标为 i-1 的位置,即数据元素的序号和存放它的数组下标之间存在对应关系如图:
其实,内存中的地址,就和图书馆或电影院里的座位一样,都是有编号的。 存储器中的每个存储单元都有自 己的编号 ,这个编号称为地址 。
假设占用的是 c 个存储单元,那么线性表中第 i+l 个数据元素的存储位置和第 i 个数据元素的存储位置满足下列关系 ( LOC 表示获得存储位置的函数)。
所以对于第 i 个数据元素 a,的存储位置可以由 a1 推算得出:
4.1获得元素操作
对于统性表的顺序存储结构来说,如果我们要实现 GetElem 操作,即将线性表 L中的第 i 个位置元素值返回,其实是非常简单的 。 就程序而言 ,只要 i 的数值在数组下标范围内,就是把数组第 i-1 下标的值返回即可 。 来看代码 :
4.2插入操作
举个例子,本来我们在春运时去买火车票,大家都排队排的好好的。这时来了一个美女,对着队伍中排在第三位的你说,"大哥,求求你帮帮忙,我家母亲有病,我得急着回去看她,这队伍这么长,你可否让我排在你的前面? "你心一软,就同意了 。
这时,你必须得退后一步,否则她是没法进到队伍来的。这可不得了 ,后面的人像蜗虫一样,全部都得退一步。骂起四声。但后面的人也不清楚这加塞是怎么回事,没什么办法。
这个例子其实已经说明了线性表的顺序存储结构,在插入数据时的实现过程:
插入算法的思路;
• 如果插入位置不合理,抛出 异常;
• 如果线性表长度大于等于数组长度,则抛出异常或动态增加容量;
• 从最后一个元素开始向前遍历到第 i 个位置,分别将它们都向后移动一个位置;
• 将要插入元素填入位置 i 处;
实现代码如下:
4.3删除操作
接着刚才的例子 。 此时后面排队的人群意见都很大,都说怎么可以这样,不管什么原因,插队就是不行,有本事,找火车站开后门去 。 就在这时,远处跑来 一胖子,对着这美女喊,可找到你了,你这骗子 ,还我钱。只见这女子二话不说,突然就冲出了队伍,胖子迫在其后,消失在人群中。哦,原来她是倒卖火车票的黄牛,刚才还装可怜。于是排队的人群,又像蠕虫一样,均向前移动了一步,骂声渐患,队伍又恢复了平静。
删除算法的思路:
• 如果删除位置不合理,抛出异常 ;
• 取出删除元素;
• 从删除元素位置开始遍历到最后 一个元素位置,分别将它们都向前移动 一个位置;
•表长减 1 。