我们现在开始重新学习线性表,先贴一下关于线性表需要学习的内容吧。
前面我们已经给了线性表的定义,现在我们来分析一下,线性表应该有一些什么样的操作呢?然后再定义线性表的ADT。
还是拿伍迷老师的精彩例子:
创建与初始化:老师为了让小朋友有秩序地出入,所以就考虑给他们排一个队,并且是长期使用的顺序,这个考虑和安排的过程其实就是一个线性表的创建和初始化过程。
置空:一开始没经验,把小朋友排好队后,发现有的高有的矮,队伍很难看,于是就让小朋友解散重新排——这是一个线性表重置为空表的操作。
获取元素:排好了队,我们随时可以叫出队伍某一位置的小朋友名字及他的具体情况。这种可以根据位序得到数据元素也是一种很重要的线性表操作。
查找:还有什么呢,有时我们想知道,某个小朋友,比如麦兜是否是班里的小朋友,老师会告诉我说,不是,麦兜在春田花花幼儿园里,不在我们幼儿园。这种査找某个元素是否存在的操作很常用。
表长度:而后有家长问老师,班里现在到底有多少个小朋友呀,这种获得线性表长度的问题也很普遍。
插入与删除。显然,对于一个幼儿园来说,加入一个新的小朋友到队列中,或因某个小朋友生病,需要移除某个位置,都是很正常的情况。对于一个线性表来说,插入数据和删除数据都是必须的操作。
线性表大概就是上面这些操作了,所以其ADT可以定义为:
ADT 线性表 (List)
Data
Operation
void initList(*L);//创建并初始化一个空线性表,如果成功返回true,修改表传指针
bool listEmpty(L);//判断一个线性表是否为空,不修改表传值
void clearList(*L);//清空一个线性表,成功返回true
bool getElem(L,i,*e);//从某个位置取出元素并赋值给e(i的范围是[1,L.length]),修改e的值所以传递一个指针,成功返回true
int locateElem(L,e);//查找线性表中是否有e,如果有返回它的位置(从1开始),否则返回0表示失败
bool listInsert(*L,i,e);//插入一个元素e在第i个元素之前(i的取值范围是[1,L.length+1]) ,成功返回true
bool listDelete(*L,i,*e);//删除在第i个位置上的元素(i的取值范围是[1,L.length]),删除的元素赋给e,成功返回true
int listLength(L);//返回线性表的元素个数
endADT
对于不同的应用,线性表的基本操作是不同的,上述操作是最基本的,对于实际问题中涉及的关于线性表的更复杂操作,完全可以用这些基本操作的组合来实现。
比如,要实现两个线性表集合A和B的并集操作。即要使得集合A=AUB。说白了,就是把存在集合B中但并不存在A中的数据元素插入到A中即可。
仔细分析一下这个操作,发现我们只要循环集合B中的毎个元素,判断当前元素是否存在A中,若不存在,则插入到A中即可。思路应该是很容易想到的。
void unionL(List *la,List lb){
int index;
int laLength = listLength(*la);//得到a的长度,需要一个线性表而不是一个地址
int lbLength = listLength(lb);}
ElemType e;//声明一个元素
for(index=1;index<=lbLength;index++){//遍历lb
getElem(lb,index,&e);//依次得到lb中的元素
if(!locateElem(*la,e)){//检查是否在la中出现
listInsert(la,++laLength,e);//没有出现则插入队尾,前自增!
}
}
}
这里,我们对于union操作,用到了前面线性表基本操作ListLength、GetElem、LocateElem、Listlnsert等,可见,对于复杂的个性化的操作,其实就是把基本操作组合起来实现的。
延伸阅读
此文章所在专题列表如下: