1、线性表的定义
线性表是最常用且最简单的一种数据结构。
一个线性表是n个数据元素的有限序列。
数据元素可以是一个数、一个符号、也可以是一幅图、一页书或更复杂的信息。
1.1线性表的类型定义
抽象数据类型线性表的定义如下:
ADT List
{ 数据对象:D={ ai | ai ∈ElemSet, i=1,2,...,n, n≥0 }
{称n为线性表的表长;称n=0时的线性表为空表}
数据关系:R1={ |ai-1 ,ai∈D, i=2,...,n }
{设线性表为(a1,a2,...ai,....an),称i为A在线性表中的位序}
基本操作:
{ 初始化 } InitList( &L )
操作结果:构造一个空的线性表L。
{ 结构销毁 } DestroyList( &L )
初始条件:线性表L已存在。 操作结果:销毁线性表L。
{ 引用型操作 }ListEmpty( L )
初始条件:线性表L已存在。 操作结果:若L为空表,则返回TRUE, 否则FALSE。
ListLength( L )
初始条件:线性表L已存在。 操作结果:返回L中元素个数。
GetElem( L, i, &e )
初始条件:线性表L已存在, 1≤i≤LengthList(L) 操作结果:用e返回L中第i个元素的值。
LocateElem( L, e, compare( ) )
初始条件:线性表L已存在,compare( ) 是元素判定函数。 操作结果:返回L中第1个与e满足关系 compare( )的元素的位序。若这样的元 素不存在,则返回值为0。
PriorElem( L, cur_e, &pre_e )
初始条件:线性表L已存在。 操作结果:若cur_e是L的元素,但不是 第一个,则用pre_e 返回它的前驱, 否则操作失败,pre_e无定义。
NextElem( L, cur_e, &next_e )
初始条件:线性表L已存在。 操作结果:若cur_e是L的元素,但不是 最后一个,则用next_e返回它的后继, 否则操作失败,next_e无定义。
ListTraverse(L, visit( ))
初始条件:线性表L已存在。 操作结果:依次对L的每个元素调用函数 visit( )。一旦visit( )失败,则操作失败。
{ 加工型操作 }
ClearList( &L )
初始条件:线性表L已存在。 操作结果:将L重置为空表。
PutElem( L, i, &e )
初始条件:线性表L已存在, 1≤i≤ListLength(L) 操作结果:L中第i个元素赋值同e的值。
ListInsert( &L, i, e )
初始条件:线性表L已存在, 1≤i≤ListLength(L)+1 操作结果:在L的第i个元素之前插入新 的元素e,L的长度增1。
ListDelete(&L, i, &e)
初始条件:线性表L已存在且非空, 1≤i≤ListLength(L) 操作结果:删除L的第i个元素,并用e 返回其值,L的长度减1。
} ADT List
2、线性结构的特点:
在数据元素的非空有限集中,
(1)存在唯一的一个被称做“第一个”的数据元素;
(2)存在唯一的一个被称做“最后一个”的数据元素;
(3)除第一个之外,集合中的每个数据元素均只有一个前驱;
(4)除最后一个之外,集合中每个数据元素均只有一个后继。
3、线性表的顺序表示:
(下一篇再研究线性表的链式表示)
用一组地址连续的存储单元依次存储线性表的数据元素。C语言中的数组即采用顺序存储方式。
LOC(ai) = LOC(ai-1) + l
(l 为一个数据元素所占存储量 )
线性表中任意一个数据元素的存储位置都可以线性表中 第一个数据元素 a1的存储地址来表示,
LOC(a i) = LOC(a 1 ) + (i-1)*I
l称第一个数据元素的存储地址为 线性表的起始地址,称作线性表的 基地址
#define LIST_INIT_SIZE 100#define LISTINCREMENT 10typedef struct{ElemType *elem; //存储空间基址int length; //当前长度int listsize; //当前分配的存储容量以一数据元素存储长度为单位}SqList;
(下面这几段代码,我觉得可能在面试的时候会让写上一段儿的。我猜的)
status ListInsert(List *L,int i,ElemType e) {struct STU *p,*q;if (i<1||i>L->length+1) return ERROR;q=&(L->elem[i-1]);for(p=&L->elem[L->length-1];p>=q;--p)*(p+1)=*p;*q=e;++L->length;return OK;}/*ListInsert Before i */
void MergeList(List *La,List *Lb,List *Lc) {ElemType *pa,*pb,*pc,*pa_last,*pb_last;pa=La->elem;pb=Lb->elem;Lc->listsize = Lc->length = La->length + Lb->length;pc = Lc->elem =(ElemType *)malloc(Lc->listsize * sizeof(ElemType));if(!Lc->elem) exit(OVERFLOW);pa_last = La->elem + La->length - 1;pb_last = Lb->elem + Lb->length - 1;while(pa<=pa_last && pb<=pb_last) {if(Less_EqualList(pa,pb)) *pc++=*pa++;else *pc++=*pb++;}while(pa<=pa_last) *pc++=*pa++;while(pb<=pb_last) *pc++=*pb++;}
int LocateElem(List *La,ElemType e,int type) {int i;switch (type) {case EQUAL:for(i=0;ielem[i],&e))return i;break;default:break;}return 0;}
void UnionList(List *La, List *Lb) {int La_len,Lb_len; int i; ElemType e;La_len=ListLength(La); Lb_len=ListLength(Lb);for(i=0;i