if(j!
=i)a[j]←→a[i]
}//select_sort
基本操作:
比较(数据元素)操作,时间复杂度:
O(n2)
四、算法的存储空间需求
算法的空间复杂度:
S(n)=O(g(n))
表示随着问题规模n的增大,算法运行所需存储量的增长率与g(n)的增长率相同。
算法的存储量包括:
1.输入数据所占空间;
2.程序本身所占空间;
3.辅助变量所占空间。
若输入数据所占空间只取决与问题本身,和算法无关,则只需要分析除输入和程序之外的额外空间。
若所需额外空间相对于输入数据量来说是常数,则称此算法为原地工作。
若所需存储量依赖于特定的输入,则通常按最坏情况考虑。
学习要点:
1.熟悉各名词、术语的含义,掌握基本概念,特别是数据的逻辑结构和存储结构之间的关系。
分清哪些是逻辑结构的性质,哪些是存储结构的性质。
2.了解抽象数据类型的定义、表示和实现方法。
3.理解算法五个要素的确切含义:
①动态有穷性(能执行结束);②确定性(对于相同的输入执行相同的路径);③有输入;④有输出;⑤可行性(用以描述算法的操作都是足够基本的)。
4.掌握计算语句频度和估算算法时间复杂度的方法。
第二章线性表
线性结构是一个数据元素的有序(次序)集
线性结构的基本特征:
1.集合中必存在唯一的一个“第一元素”;
2.集合中必存在唯一的一个“最后元素”;
3.除最后元素在外,均有唯一的后继;
4.除第一元素之外,均有唯一的前驱。
§2.1线性表的逻辑结构
一、线性表的类型定义
抽象数据类型线性表的定义如下:
ADTList{
数据对象:
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为ai在线性表中的位序。
}
二、基本操作:
{结构初始化}
1.InitList(&L)
操作结果:
构造一个空的线性表L。
{销毁结构}
2.DestroyList(&L)
初始条件:
线性表L已存在。
操作结果:
销毁线性表L。
{引用型操作}
3.ListEmpty(L)
初始条件:
线性表L已存在。
操作结果:
若L为空表,则返回TRUE,否则FALSE。
4.ListLength(L)
初始条件:
线性表L已存在。
操作结果:
返回L中元素个数。
5.PriorElem(L,cur_e,&pre_e)
初始条件:
线性表L已存在。
操作结果:
若cur_e是L的元素,但不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义。
6.NextElem(L,cur_e,&next_e)
初始条件:
线性表L已存在。
操作结果:
若cur_e是L的元素,但不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义。
7.GetElem(L,cur_e,&next_e)
初始条件:
线性表L已存在,1≤i≤LengthList(L)
操作结果:
用e返回L中第i个元素的值。
8.LocateElem(L,e,compare())
初始条件:
线性表L已存在,compare()是元素判定函数。
操作结果:
返回L中第1个与e满足关系compare()的元素的位序。
若这样的元素不存在,则返回值为0。
9.ListTraverse(L,visit())
初始条件:
线性表L已存在。
操作结果:
依次对L的每个元素调用函数visit()。
一旦visit()失败,则操作失败。
{加工型操作}
10.ClearList(&L)
初始条件:
线性表L已存在。
操作结果:
将L重置为空表。
11.PutElem(L,i,&e)
初始条件:
线性表L已存在,1≤i≤LengthList(L)
操作结果:
L中第i个元素赋值同e的值。
12.ListInsert(&L,i,e)
初始条件:
线性表L已存在,1≤i≤LengthList(L)+1
操作结果:
在L的第i个元素之前插入新的元素e,L的长度增1。
13.ListDelete(&L,i,&e)
初始条件:
线性表L已存在且非空,1≤i≤LengthList(L)
操作结果:
删除L的第i个元素,并用e返回其值,L的长度减1。
}ADTList
利用上述定义的线性表可以完成其它更复杂的操作
例2-1假设有两个集合A和B分别用两个线性表LA和LB表示(即:
线性表中的数据元素即为集合中的成员),现要求一个新的集合A=A∪B。
上述问题可演绎为,要求对线性表作如下操作:
扩大线性表LA,将存在于线性表LB中而不存在于线性表LA中的数据元素插入到线性表LA中去。
1.从线性表LB中依次取得每个数据元素;GetElem(LB,i)→e
2.依值在线性表LA中进行查访;LocateElem(LA,e,equal())
3.若不存在,则插入之。
ListInsert(LA,n+1,e)
voidunion(List&La,ListLb){
//将所有在线性表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())
ListInsert(La,++La_len1,e);
//La中不存在和e相同的数据元素,则插入之
}
}//union
例2-2已知一个非纯集合B,试构造一个纯集合A,使A中只包含B中所有值各不相同的数据元素。
voidpurge(List&La,ListLb){
//已知线性表Lb中的数据元素依值非递减有序排列(Lb是有序表),
//构造线性表La,使其只包含Lb中所有值不相同的数据元素
InitList(LA);
La_len=ListLength(La);
Lb_len=ListLength(Lb);//求线性表的长度
for(i=1;i<=Lb_len;i++){
GetElem(Lb,i,e);//取Lb中第i个数据元素赋给e
if(!
equal(en,e)){
ListInsert(La,++La_len,e);
en=e;
}//La中不存在和e相同的数据元素,则插入之
}
}//purge
例2-3归并两个“其数据元素按值非递减有序排列的”线性表LA和LB,求得线性表LC也具有同样特性
设La=(a1,…,ai,…,an)
Lb=(b1,…,bj,…,bm)
Lc=(c1,…,ck,…,cm+n)
则Ck=k=1,2,…,m+n
1.分别从LA和LB中取得当前元素ai和bj;
2.若ai≤bj,则将ai插入到LC中,否则将bj插入到LC中。
voidMergeList(ListLa,ListLb,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)){
//La和Lb均非空
GetElem(La,i,ai);GetElem(Lb,j,bj);
if(ai<=bj){
ListInsert(Lc,++k,ai);++i;}
else{ListInsert(Lc,++k,bj);++j;}
}
while(i<=La_len){
GetElem(La,i++,ai);
ListInsert(Lc,++k,ai);
}
while(j<=Lb_len){
GetElem(Lb,j++,bj);
ListInsert(Lc,++k,bj);
}
}//merge_list
§2.2线性表的顺序存储和基本操作的实现
一、顺序表
用一组地址连续的存储单元依次存放线性表中的数据元素,线性表的起始地址,称作线性表的基地址,以“存储位置相邻”表示有序对即:
所有数据元素的存储位置均取决于第一个数据元素的存储位置
Loc(ai)=Loc(a1)+(I-1)*l,1≤i≤n,l=sizeof(ElemType)
顺序映像的C语言描述
//-----线性表的动态分配顺序存储结构-----
#defineLIST_INIT_SIZE80//线性表存储空间的初始分配量
#defineLISTINCREMENT10//线性表存储空间的分配增量
typedefstruct{
ElemType*elem;//存储空间基址
intlength;//当前长度
intlistsize;//当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;//俗称顺序表
二、线性表的基本操作的实现
1、初始化在顺序映像中的实现
StatusInitList_Sq(SqList&L){
//构造一个空的线性表L。
L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!
L.elem)exit(OVERFLOW);//存储分配失败
L.length=0;//长度为0
L.listsize=LIST_INIT_SIZE;//初始存储容量
returnOK;
}//InitList_Sq
2、线性表的建立
StatusCreaList_Sq(SqList&L){intlength,i,data;printf("输入表的长度\n");scanf("%d",&length);InitList_Sq(L);printf("输入表中数据\n");
for(i=0;i{
scanf("%d",&data);
L.elem[i]=data;
}
L.length=length;
returnOK;
}//Crea_Sq
3、线性表操作LocateElem(L,e,compare())的实现:
intLocateElem_Sq(SqListL,ElemTypee,Status(*compare)(ElemType,ElemType)){
//在顺序线性表L中查找第1个值与e满足compare()的元素的位序。
//若找到,则返回其在L中的位序,否则返回0。
i=1;//i的初值为第1元素的位序
p=L.elem;//p的初值为第1元素的存储位置
while(i<=L.length&&!
(*compare)(*p++,e))++i;
if(i<=L.length)returni;
else