您的位置:首页 > 理论基础 > 数据结构算法

【Data】数据结构之线性表(1)

2013-04-28 21:53 176 查看
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 10

typedef 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;i<length;i++)
if(EqualList(&La->elem[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<Lb_len;i++) {
GetElem(*Lb,i,&e);
if(!LocateElem(La,e,EQUAL))
ListInsert(La,++La_len,e);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: