大数据结构C语言2.docx
《大数据结构C语言2.docx》由会员分享,可在线阅读,更多相关《大数据结构C语言2.docx(53页珍藏版)》请在冰豆网上搜索。
大数据结构C语言2
第二章线性表
本章的重点:
掌握顺序表和单链表上实现的各种基本算法及相关的时间性能分析;
难点:
使用本章所学的基本知识设计有效算法解决与线性表相关的应用问题。
要求达到“识记”的内容:
线性表的逻辑结构特征,线性表上定义的基本运算,并利用基本运算构造出较复杂的运算。
要求达到“综合应用”的内容:
顺序表的含义及特点,顺序表上的插入、删除操作,解决简单应用问题。
链表如何表示线性表中元素之间的逻辑关系;单链表、双链表、循环链表链接方式上的区别;单链表上实现的建表、查找、插入和删除等基本算法及其时间复杂度。
循环链表上尾指针取代头指针的作用,以及单循环链表上的算法与单链表上相应算法的异同点。
双链表的定义和相关算法。
利用链表设计算法解决简单应用问题。
要求达到“领会”的内容:
顺序表和链表的比较,以及如何选择其一作为其存储结构才能取得较优的时空性能。
线性结构的特点:
在数据元素的非空有限集中,
⑴存在唯一的一个被称做“第一个”的数据元素;
⑵存在唯一的一个被称做“最后一个”的数据元素;
⑶除第一个之外,集合中的每个数据元素均只有一个前驱;
⑷除最后一个之外,集合中每个数据元素均只有一个后继。
2.1线性表的逻辑结构
一、线性表的定义
线性表是最常用且最简单的一种数据结构。
一个线性表是n个数据元素的有限序列。
数据元素可以是一个数、一个符号、也可以是一幅图、一页书或更复杂的信息。
线性表例:
1、
1
2
3
4
5
6
7
2、
3、
学号
姓名
语文
数学
C语言
6201001
张三
85
54
92
6201002
李四
92
84
64
6201003
王五
87
74
73
6201004
...
数据元素也可由若干个数据项组成(如上例3)。
这时常把数据元素称为记录。
含有大量记录的线性表又称文件。
线性表中的数据元素类型多种多样,但同一线性表中的元素必定具有相同特性,即属同一数据对象,相邻数据元素之间存在着序偶关系。
a1
...
ai-1
ai
ai+1
...
an
ai是ai+1的直接前驱元素,ai+1是ai的直接后继元素。
线性表中元素的个数n定义为线性表的长度,为0时称为空表。
在非空表中的每个数据元素都有一个确定的位置。
ai是第i个元素,把i称为数据元素ai在线性中的位序。
二、线性表的类型定义
⒈抽象数据类型线性表的定义如下:
ADTList{
数据对象:
D={ai|ai(-ElemSet,i=1,2,...,n,n>=0}
数据关系:
R1={|ai-1,ai(-D,i=2,...,n}
基本操作:
InitList(&L)
DestroyList(&L)
ClearList(&L)
ListEmpty(L)
ListLength(L)
GetElem(L,i,&e)
LocateElem(L,e,compare())
PriorElem(L,cur_e,&pre_e)
NextElem(L,cur_e,&next_e)
ListInsert(&L,i,e)
ListDelete(&L,i,&e)
ListTraverse(L,visit())
}ADTList
2、部分操作的类C实现:
InitList(&L)
{L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!
L.elem)exit(OVERFLOW);
L.length=0;
L.listsize=LIST_INIT_SIZE;
returnOK;
}//InitList
GetElem(L,i,&e)
{*e=L.lem[i]
}//GetElem
ListInsert(List&L,inti,ElemTypee)
{if(i<1||i>L.length+1)returnERROR;
q=&(L.elem[i-1]);
for(p=&(L.elem[L.length-1]);p>=q;--p)*(p+1)=*p;
*q=e;
++L.length;
returnOK;
}//ListInsert
voidunion(List&La,List&Lb)
//利用两个线性表LA和LB分别表示两个集合A和B,现要求一个新的集合A=A∪B。
La_len=ListLength(La);Lb_len=ListLength(Lb);
for(i=1;i<=Lb_len;i++){
GetElem(Lb,i,e);
if(!
LocateElem(La,e,equal))
ListInsert(La,++La_len,e);
}//union
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)&&(jGetElem(La,i,ai);GetElem(Lb,j,bj);
if(ai<=bj){ListInsert(Lc,++k,ai);++i;}
else{ListInsert(Lc,++k,bj);++j;}
}
while(k<=La_len){
GetElem(La,i++,ai);ListInsert(Lc,++k,ai);
}
while(j<=Lb_len){
GetElem(Lb,j++,bj);ListInsert(Lc,++k,bj);
}
}//MergeList
3、部分操作的C语言实现,
#include
#include
#include
#defineERROR0
#defineOK1
#defineEQUAL1
structSTU{
charname[20];
charstuno[10];
intage;
intscore;
}stu[50];
typedefstructSTUElemType;
structLIST
{ElemTypeelem[50];
intlength;
};
typedefstructLISTList;
intinit(List**L)
{*L=(List*)malloc(sizeof(List));
(*L)->length=0;
}
intListLength(List*L)
{returnL->length;
}
voidGetElem(ListL,inti,ElemType*e)
{*e=L.elem[i];
}
intEqualList(ElemType*e1,ElemType*e2)
{if(strcmp(e1->name,e2->name))
return0;
if(strcmp(e1->stuno,e2->stuno))
return0;
if(e1->age!
=e2->age)
return0;
if(e1->score!
=e2->score)
return0;
return1;
}
intLocateElem(List*La,ElemTypee,inttype)
{inti;
switch(type)
{caseEQUAL:
for(i=0;ilength;i++)
if(EqualList(&La->elem[i],&e))
return1;
break;
default:
break;
}
return0;
}
voidUnionList(List*La,List*Lb)
{
intLa_len,Lb_len;
inti;
ElemTypee;
La_len=ListLength(La);Lb_len=ListLength(Lb);
for(i=0;iL->length+1)returnERROR;
q=&(L->elem[i-1]);
for(p=&L->elem[L->length-1];p>=q;--p)
*(p+1)=*p;
*q=e;
++L->length;
returnOK;
}/*ListInsertBeforei*/
main()
{structSTUe;
List*La,*Lb;
clrscr();
printf("\n\n-------------------ListDemoisrunning...----------------\n\n");
printf("FirstisInsertListfunction.\n");
init(&La);
strcpy(e.name,"stu1");
strcpy(e.stuno,"100001");
e.age=80;
e.score=1000;
ListInsert(La,1,e);
strcpy(e.name,"stu2");
strcpy(e.stuno,"100002");
e.age=80;
e.score=1000;
ListInsert(La,2,e);
printlist(*La);
printf("ListAlengthnowis%d.\n\n",La->length);
getch();
strcpy(e.name,"stu3");
strcpy(e.stuno,"100003");
e.age=80;
e.score=1000;
ListInsert(La,3,e);
printlist(*La);
printf("ListAlengthnowis%d.\n\n",La->length);
getch();
init(&Lb);
strcpy(e.name,"zmofun");
strcpy(e.stuno,"100001");
e.age=80;
e.score=1000;
ListInsert(Lb,1,e);
strcpy(e.name,"bobjin");
strcpy(e.stuno,"100002");
e.age=80;
e.score=1000;
ListInsert(Lb,2,e);
strcpy(e.name,"stu1");
strcpy(e.stuno,"100001");
e.age=80;
e.score=1000;
ListInsert(Lb,3,e);
printlist(*Lb);
printf("ListBlengthnowis%d.\n\n",Lb->length);
getch();
printf("SecondisUnionListfunction.\n");
printf("NowunionListAandListB.....\n");
UnionList(La,Lb);
printlist(*La);
printf("ListAlengthnowis%d.\n\n",La->length);
getch();
clrscr();
}
2.2线性表的顺序表示和实现
⑴存储结构
逻辑结构
“数据结构”定义中的“关系”指数据间的逻辑关系,故也称数据结构为逻辑结构。
存储结构
顺序
数据结构在计算机中的表示称为物理结构。
又称存储结构。
链式
⑵线性表的类型定义
一、线性表的顺序表示
用一组地址连续的存储单元依次存储线性表的数据元素。
C语言中的数组即采用顺序存储方式。
2000:
0001
2000:
0003
2000:
0005
2000:
0007
2000:
0009
2000:
0011
2000:
0013
2000:
0015
2000:
0017
...
2000:
1001
2000:
1003
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
1
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
1
a[9]
1
2
3
4
5
6
7
8
9
假设线性表的每个元素需占用l个存储单元,并以所占的第一个单元的存储地址作为数据元素的存储位置。
则存在如下关系:
LOC(ai+1)=LOC(ai)+l
LOC(ai)=LOC(a1)+(i-1)*l
式中LOC(a1)是线性表的第一个数据元素的存储位置,通常称做线性表的起始位置或基地址。
常用b表示。
线性表的这种机内表示称做线性表的顺序存储结构或顺序映象。
称顺序存储结构的线性表为顺序表。
顺序表的特点是以元素在计算机内物理位置相邻来表示线性表中数据元素之间的逻辑关系。
二、顺序存储结构的线性表操作及C语言实现:
线性表的动态分配顺序存储结构
#defineLIST_INIT_SIZE100
#defineLISTINCREMENT10
typedefstruct{
ElemType*elem;//存储空间基址
intlength;//当前长度
intlistsize;//当前分配的存储容量以一数据元素存储长度为单位
}SqList;
顺序表的插入与删除操作:
序号
数据元素
序号
数据元素
序号
数据元素
序号
数据元素
1
2
3
4
5
6
7
8
9
12
13
21
24
28
30
42
77
<-25
1
2
3
4
5
6
7
8
9
12
13
21
24
25
28
30
42
77
1
2
3
4
5
6
7
8
9
12
13
21
24
28
30
42
77
->24
1
2
3
4
5
6
7
8
9
12
13
21
28
30
42
77
插入前n=8;插入后n=9;
删除前n=8;删除后n=7;
顺序表的插入算法
statusListInsert(List*L,inti,ElemTypee){
structSTU*p,*q;
if(i<1||i>L->length+1)returnERROR;
q=&(L->elem[i-1]);
for(p=&L->elem[L->length-1];p>=q;--p)
*(p+1)=*p;
*q=e;
++L->length;
returnOK;
}/*ListInsertBeforei*/
顺序表的合并算法
voidMergeList(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++;
}
顺序表的查找算法
intLocateElem(List*La,ElemTypee,inttype){
inti;switch(type){
caseEQUAL:
for(i=0;iif(EqualList(&La->elem[i],&e))
return1;
break;
default:
break;
}
return0;
}
顺序表的联合算法
voidUnionList(List*La,List*Lb){
intLa_len,Lb_len;inti;ElemTypee;
La_len=ListLength(La);Lb_len=ListLength(Lb);
for(i=0;iGetElem(*Lb,i,&e);
if(!
LocateElem(La,e,EQUAL))
ListInsert(La,++La_len,e);
}
}
三、C语言源程序范例
#include
#include
#include
#defineERROR0
#defineOK1
#defineEQUAL1
#defineOVERFLOW-1
#defineLIST_INIT_SIZE100
#defineLISTINCREMENT10
structSTU{
charname[20];
charstuno[10];
intage;
intscore;
}stu[50];
typedefstructSTUElemType;
structLIST
{
ElemType*elem;
intlength;
intlistsize;
};
typedefstructLISTList;
intinit(List*L)
{
L->elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!
L->elem)exit(OVERFLOW);
L->length=0;
L->listsize=LIST_INIT_SIZE;
returnOK;
}/*init*/
intListLength(List*L)
{
returnL->length;
}
voidGetElem(ListL,inti,ElemType*e)
{
*e=L.elem[i];
}
intEqualList(ElemType*e1,ElemType*e2)
{
if(strcmp(e1->name,e2->name)==0)
return1;
else
return0;
}
intLess_EqualList(ElemType*e1,ElemType*e2)
{
if(strcmp(e1->name,e2->name)<=0)
return1;
else
return0;
}
intLocateElem(List*La,ElemTypee,inttype)
{
inti;
switch(type)
{
caseEQUAL:
for(i=0;ilength;i++)
if(EqualList(&La->elem[i],&e))
return1;
break;
default:
break;
}
return0;
}
voidMergeList(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<=