ADT(array data table)线性表
Data
线性表的数据对象集合为{$a_1,a_2,a_3...a_n$},每个元素的类型均为DataType。其中,除第一个元素$a_1$外,每一个元素有且只有一个直接前驱元素,除了最后一个元素$a_n$外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。
Operation(基本函数):
/* InitList(*L); 初始化操作,建立一个空的线性表L。 ListEmpty(L); 若线性表为空,返回true,否则返回false。 ClearList(*L); 将线性表清空。 GetElem(L,i,*e); 将线性表L中的第i个位置元素值返回给e。 LocateElem(L,e); 在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素在表中序号表示成功;否则,返回0表示失败。 ListInsert(*L,i,e); 在线性表L中的第i个位置插入新元素e。 ListDelete(*L,i,*e); 删除线性表L中第i个位置的元素,并用e返回其值。 ListLength(L); 返回线性表L的元素个数。 */
线性表的顺序存储结构代码:
#define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int Status; //Status是函数的返回类型,其值是函数结果状态代码,如OK等 #define MAXSIZE 20 /*存储空间初始化分配量*/ typedef int ElemType; /*ElemType 类型根据实际情况而定,这里假设为int */ typedef struct { ElemType data[MAXSIZE]; /*数组存储元素,最大值为MAXSIZE*/ int length; /*线性表当前长度*/ } SqList; //GetElem(L,i,*e) 获取元素接口实现 //初始条件:顺序线性表L已存在,1<=i <=ListLength(L) //操作结果:用e返回L中第i个数据元素的值 Status GetElem(SqList L, int i, ElemType *e) { if(L.length==0 || i<1 || i>L.length) return ERROR; *e=L.data[i-1]; return OK; } //ListInsert(*L,i,e) 在线性表L中的第i个位置插入新元素e //初始条件:顺序线性表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) /*若插入的位置不在表尾*/ { //重点1:数组后移的遍历方式 for(k=L->length-1;k>=i-1;k--) /*将要插入位置后数据元素向后移动一位*/ L->data[k+1]=L->data[k]; } L->data[i-1]=e; /*将新元素插入*/ L->length++; return OK; } //ListDelete(*L,i,*e) 删除线性表L中第i个位置的元素,并用e返回其值 //初始条件:顺序线性表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) /*删除位置不正确*/ return ERROR; *e=L->data[i-1]; if(i<L->length) /*如果删除不是最后位置*/ { //重点2:从头到后遍历的方式一定不能有这种思想 for(k=i; k<L->length;k++) /*将删除位置后继元素前移*/ L->data[k-1]=L->data[k]; } L->length--; return OK; }
线性表的优缺点
优点:
无须为表示表中元素之间的逻辑关系儿增加额外的存储关系
可以快速地存取表中任一位置的元素
缺点:
插入和删除操作需要移动大量元素
当线性表长度变化较大时,难以确定存储空间的容量
造成存储空间的“碎片”