您的位置:首页 > 其它

第2章 线性表——2.1 线性表的类型定义

2013-07-29 16:45 288 查看
线性表是最常用且最简单的数据结构。线性表中的数据元素可以是很多种简单的字符、字母等和稍微复杂其它种。

例如:26个英文字母的字母表:

(A,B,C,D,E……Z)

是一个线性表,表中的数据元素是单个字母字符。

稍微复杂的线性表中,一个数据元素可以由若干个数据项组成。在这种情况下,常把数据元素称为记录(record),含有大量记录的线性表又称为文件(file)。

例如:一个学校的学生信息登记表,表中有姓名、性别、年龄、班级等数据项组成。

线性表是一个相当灵活的数据结构,它的长度可增加和缩减;对线性表的数据元素不仅可以访问,还可以插入或删除。

抽象数据类型的线性表的定义如下:

ADT List{

数据对象:D = {ai | ai∈ElemSet,i = 1,2,3…n,n>=0}

数据关系:R1 = {<a(i-1),ai> | a(i-1), ai∈D,i = 2,……,n}

基本操作:

InitList(&L)

操作结果:构造一个空的线性表L。

DestroyList(&L)

操作结果:销毁线性表L。

ClearList(&L)

操作结果:清空线性表L。

ListEmpty(L)

操作结果:若线性表L为空返回TRUE,否则返回FALSE。

ListLength(L)

操作结果:返回L中数据元素的个数。

GetElem(L,i,&e)

操作结果:用e返回线性表L中的第i个元素。

LocateElem(L,e,compare())

操作结果:返回L中第一个与e满足关系compare()的数据元素的位序。若L中这样的元素不存在,则返回值为0。

PriorElem(L,cur_e,&pre_e)

操作结果:若cur_e是L的数据元素,且不是第一个(也就是说不是第一个它有前驱),那么用pre_e返回它的前驱;否则操作失败,pre_e无定义。

NextElem(L,cur_e,&next_e)

操作结果:若cur_e是L的数据元素,且不是最后一个(也就是说不是最后一个它有后继),那么用next_e返回它的后继;否则失败;

ListInsert(&L,i,e)

操作结果:在L中的第i个位置之前插入新的数据元素e,L的长度加1。

ListDelete(&L,i,&e)

操作结果:删除L中的第i个元素,并用e返回其值,L的长度减1。

ListTraverse(L,visit())

操作结果:依次对L中的每个数据元素调用函数visit()。一旦visit()失败,则操作失败。

}ADT List

对于上述定义的抽象数据类型线性表,还可以进行一些更复杂的操作,例如将两个或两个以上的线性表合并成一个;将一个线性表拆分成两个或两个以上的线性表;复制一个线性表等。

例2-1
假设利用两个线性表LA和LB分别表示两个集合A和B(即线性表中的数据元素即为集合中的成员),先要求一个新的集合A=AUB。这就要求对线性表作如下操作:扩大线性表LA,将存在于线性表LB中而在LA中不存在的数据元素插入到线性表LA中。只有从线性表LB中取得元素,并以值在线性表LA中进行查访,若不存在就插入。

上述操作过程可用下面算法描述之。

算法2.1:

void union(List &La,List Lb)
{
//将所有线性表Lb中但不在La中的数据元素插入La;
La_len = ListLength(La);Lb_len = ListLength(Lb); //求线性表的长度;
for(i = 1; i <= lb_len; i++)
{
GetElem(Lb, i, e);//取Lb中第i个元素赋给e
//这就是算法?
if(!LocateElem(la, e, equal))//La中不存在和e相同的元素;条件判断Lb中的元素在La中是否存在。
ListInsert(La, ++La_len, e);//则将e插入La;
}
}


例2.2:已知线性表LA和LB中的数据元素按非递减有序排列,现在要求将LA和LB归并为一个新的线性表LC,且LC中的元素是按非递减有序排列。例如,设

LA = (3,5,8,11)

LB = (2,6,8,9,11,15,20)

则 LC = (2,3,5,8,8,9,11,11,15,20)

从上述问题要求可知,LC中的数据元素或是LA中的数据元素,或是LB中的数据元素,则只要先将LC设为空,然后将LA和LB中的元素琢个插入到LC中即可。为使LC中的元素按值非递减有序排列,可设两个指针i和j分别指向LA和LB中的元素,若设i所指的当前元素为a,j当前所指的元素为b,则当前应插入到LC中的元素c为

c = a 当a<=b时;c = b 当a>b时。

指针i和j的初值均为1,在所指元素插入LC之后,i和j在LA和LB中顺序后移。

上述归并算法如算法2.2如下所示。

算法2.2:

void MergList(List La,List Lb,List &Lc)
{
//已知线性表La和Lb 中的数据元素按值非递减排列。
//归并La和Lb得到新的线性表Lc,Lc数据元素也按非递减排列。
InitList(Lc);
i = j = 1; k = 0;
La_len = ListLength(La);lb_len = ListLength(Lb);
while((i <= La_len)&&(j <= Lb_len))
{
GetElem(La, i, ai); GetElem(Lb,j, bj);
if(ai <= bj)
{
ListInsert(Lc, ++k,  ai);
++i;
}
else
{
ListInsert(Lc, ++k, bj);
++j;
}
}
//当一个线性表的元素已经全部插入后,只要将另一个线性表的元素按顺序插入即可,下面两个(while)循环语句执行一个循环体——即只会有一个会执行。
while(i <= La_len)
{
GetElem(La, i, ai);
ListInsert(Lc, ++k,  ai);
}
while(j <= Lb_len)
{
GetElem(Lb,j, bj);
ListInsert(Lc, ++k,  bj);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: