第二章 线性表
2.1 线性表的基本概念
线性结构的基本种类:
1. 线性表(最为典型)
2. 栈/队列(样本受限)
3. 串(权限受限)
4. 数据和广义表
2.1.1 线性表的定义
线性表是最基本、应用最广泛的一种数据结构。
线性表:是由n(n>=0)个具有相同类型的数据元素a1、a2、···、an组成的有限序列。其中:这些元素称之为结点、记录或表目。通常,把非空的线性表记为:
L=(a1、a2、···、ai、···、an)
其中:
1. L是一个线性表名。一个线性表可以用一个标识符命名。
2. n成为线性表的长度,即线性表中的数据元素的个数。当n=0时,成线性表为空表,表中不包含任何数据元素;当n>0时,则称其为非空线性表。
3. ai(1<=i<=n)是线性表中的数据元素。(每个数据元素都具有相同的数据类型,其数据类型根据具体情况而定)。
线性表中的元素存在先后次序的关系。
2.1.2 线性表的抽象数据类型(ADT)
线性表的ADT:(这个东西看看就好,平时多练习)
ADT List{
数据对象:D={ai|ai∈ElemSet,i=1,2,···,n,n>=0}
数据关系:R={<ai-1,a>|ai-1,ai∈D,i=1,2,···,n}
基本操作:
LinearList*Init_List() //创建线性表
初始条件:线性表L不存在;
操作结果:构造一个空的线性表。
void Destory_List(LinearList*L) //销毁线性表
初始条件:线性表L已经存在;
操作结果:销毁线性表L。
LinearList*Clear_List(LinearList*L) //清空线性表
初始条件:线性表L已经存在;
操作结果:将线性表L置为空表。
int List_Empty(LinearList*L) //判断线性表是否为空表
初始条件:线性表L已经存在;
操作结果:若L为空表,则返回TURE(或1);否则返回 FALSE(或0)。
int List_Length(LinearList*L) //计算线性表中数据元素的个数
初始条件:线性表L已经存在;
操作结果:返回L中数据元素的个数。
ElemtypeGetData_List(LinearList*L,int i) //取出第i个元素
初始条件:线性表L已经存在,并且满足条件1<=i<=ListLength(L);
操作结果:将L中第i个元素返回。
Int Search_List(LinearList*L,elemtypee,int compare())//比较元素
初始条件:线性表L已经存在;
操作结果:返回L中第一个与e满足compare()的数据元
素的位序。若这样的数据元素不存在,则返回值为0.
voidPriorElem(LinearList*L,elemtype cur_e,elemtype*pre_e)//求出前驱元素
初始条件:线性表L已经存在;
操作结果:若cur_e是L的数据元素,而且不是第一个数
据元素,则用pre_e返回它的前驱;否则操作失败pre_e
无意义。
voidNextElem(LinearList*L,elemtype cur_e,elemtype*next_e)//求出后继元素
初始条件:线性表L已经存在;
操作结果:若cur_e是L的数据元素,而且不是最后一个
数据元素,则用next_e返回它的后继;否则操作失败,
next_e无意义。
LinearList*Insert_List(LinearList*L,intI,elemtype e)//插入元素
初始条件:线性表L已经存在,并且满足
1<=i<=ListLength(L)+1;
操作结果:在L中的第i个位置之前插入新的数据元素e,
L的长度加1。
LinearList*Delete_List(LinearList*L,intI,elemtype*e)//删除元素
初始条件:线性表L已经存在且非空,满足条件
1<=i<=ListLength(L)+1;
操作结果:删除L中的第i个元素,并用e返回其值,
L的长度减1。
int TraverseList(LinearList*L,visit())//访问元素
初始条件:线性表L已经存在;
操作结果依次对L的每个元素调用函数visit(),一旦
visit()失败,则操作失败。
}ADT List;
2.1.3 线性表的存储结构
1.顺序表:定长的顺序存储结构。
2.链表:变长的线性存储结构(即链式存储结构)
2.2 线性表的顺序存储结构——顺序表
顺序表(sequenlist):按顺序方式存储的线性表,通过创建数组建立。
2.2.1 顺序表的定义
顺序表:指将线性表的所有数据元素,按其逻辑顺序依次存储在一组连续的内存单元中的存储形式的线性表。
特点:逻辑关系相邻的两个数据元素在物理位置上也相邻,即利用存储位置上的相邻实现数据之间的相邻逻辑关系。
第i个数据地址公式:
Loc(ai)= Loc(a1)+(i-1)*d
其中:(1<=i<=n),Loc(a1)是基址,d是存储单元。
2.2.2 顺序表的基本运算
1.顺序表的初始化:构造一个空表。
例如:将L设为顺序表指针变量,首先申请动态分配内存空间,若成功,则将L的last成员变量置为-1(因为此时表中还没有任何数据元素),然后返回申请的内存空间地址,即为顺序表的首地址;如果申请分配内存空间失败,则返回空指针。
2.求顺序表的长度:顺序表结构类型中成员last只想顺序表中的最后一个元素的下标位置,所以顺序表的长度为:L→last+1。
3.插入(insert):线性表的插入运算是指在表的第i个位置上插入一个值为x的新结点,插入后是长度为n的线性表
(a1,a2,···,ai-1,ai,···,an)
变成长度为n+1的线性表
(a1,a2,···,ai-1,x,ai,···,an)
实现步骤:
(1)检查顺序表的存储空间是否已满,若曼则插入失败返回值为0,否则进行第(2)步。
(2)检测插入的位置i是否合法,如果位置i<1或者i>L->last+2,则插入位置非法,插入操作失败返回值为-1,否则进行第(3)步。
(3)将第i ~ n个结点之间的所有节点一次向后以后一个位置,空出第i个位置。
(4)将新结点x插入到第i个位置。
(5)修改顺序表的长度,即使其加1,插入成功,返回值为1。
插入运算示意图:
本算法应注意的问题:
① 顺序表的区域只有MAXSIZE个存储单元,所以在顺序表中插入数据时需要先检查表的空间是否已满,如果已满就不可以进行插入操作,否则会溢出。
② 对插入位置进行有效性检查,插入位置i的有效范围是1<=i<=n+1,其中n为原始表长。
③ 在插入过程中要注意数据的移动方向。
4. 删除(delete)