数据结构.docx
- 文档编号:3963154
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:100
- 大小:58.87KB
数据结构.docx
《数据结构.docx》由会员分享,可在线阅读,更多相关《数据结构.docx(100页珍藏版)》请在冰豆网上搜索。
数据结构
第二章线性表
从第二章到第四章是线性结构。
线性结构的特点是:
在数据元素的非空有限集中
(1)存在唯一的一个被称做“第一个”的数据元素;
(2)存在唯一的一个被称做“最后一个”的数据元素;
(3)除第一个之外,集合中和每个元素均只有一个前驱;
(4)除最后一个之外,集合中每个数据元素均只有一个后继。
2.1线性表的类型定义:
ADTList{
数据对象:
D={ai|ai∈Elemset,i=1,2,…,n,n>0}
数据关系:
R1={
基本操作:
Initlist(&L)
操作结果:
构造一个空的线性表L。
DestroyList(&L)
初始条件:
线性表L已存在。
cearlist(&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-1利用线性表表示两个集合A和B,现在要求一个新的集合A=A∪B。
算法voidunion(List&La,ListLb)
{La_len=listgength(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
例2-2已知线性表LA和LB中的数据元素按值非递减有序排列,现要求将LA和LB归并为一个新的线性表LC,
算法:
voidMergeList(ListLa,ListLb,List&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,by);++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);}
}
}//MergeList
线性表的动态分配顺序存储结构:
#defineLIST_INIT_SIZE100
#defineLISTINCREMENT10
typedefstruct{
ElemType*elem;
Intlength;
Intlistsize;
}SqList;
构造一个空的线性表L。
StatusInitList_Sq(SqList&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_Sq
算法2.4在顺序表L中第I个位置之前插入一个元素
StatusListInsert_sq(SqList&L,intI,ElemTypee)
{if(i<1||i>L.length+1)returnError;
if(L.length>=L.lostsize)
newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if(!
newbase)exit(OVERFLOW);
L.elem=newbase;
L.listsize+=LISTINCREMENT;
}
q=&(L.elem[L.length-1]);
p>=q;--p)*(p+1)=*p;
*q=e;
++L.length;
returnok;
}//ListInsert_Sq
算法2.5在顺序线性表L中删除第I个元素,并用E返回其值
StatusListDelete_Sq(SqList&L,intI,ElemType&e)
{if((i<1)||(i>L.length))returnError;
p=*(L.elem[i-1]);
e=*p;
q=L.elem+L.length-1;
for(++p;p<=q;++p)
*(p-1)=*p;
--L.length;
returnOk;
}//ListDelete_Sq
算法2.6在顺序线性表L中查找第1个与E满号COMPARE()的元素的位序
intLocateElem_Sq(SqListL,ElemTypee,Status(*compare)(ElemType,ElemType))
{
i=1;
p=L.elem;
while(i<=L.length&&!
(*compare)(*p++,e))
{++i;}
if(i<=L.length)
returnI;
elsereturn0;
}//LocateElem_Sq
算法2.7顺序表的合并
voidMergeList_Sq(SqListLa,SqListLb,SqLIst&Lc)
{
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)
*pc++=*pa++;
while(pb<=pb_last)
*pc++=*pb++;
}//MergeList_Sq
线性表的单链表存储结构
typedefstructLnode
{
ElemTypedata;
StructLnode*next;
}Lnode,*LinkList;
单链表是非随机存取的存储结构
算法2..8函数GetElem在单链表中的实现
StatusGetElem_L(LinkListL,inti,ElemType&e)
{p=L->next;
j=1;
while(p&&j
{p=p->next;
++j;}
if(!
p||j>i)returnERROR;
e=p->data;
returnOk;
}//GetElem_L
插入结点:
s->next=p->next;p->next=s;
删除结点:
p->next=p->next->next;
算法2.9ListInsert在链表中实现插入:
statusListInsert_L(LinkList&l,inti,ElemTypee)
{
//在带头结点的单链线性表L中第I个位置之前插入元素E
p=L;
j=0;
while(p&&j
if(!
p||j>i-1)returnError;
s=(LinkList)malloc(sizeof(Lnode));
p->next=s;
returnok;
}//ListInsert_L
算法2.10删除一个结点:
StatusListDelete_L(LinkList&L,inti,ElemType&e)
{
p=L;
j=0;
while(p->next&&j p=p->next;++j;} if(I(p->next||j>i-1)returnERROr; q=p->next; p->next=q->next; e=q->data;free(q); returnok; }//ListDelete_L 算法2.11逆位序输入N个元素的值,建立带头结点的单链表L。 voidCreateList_L(LinkList&L,intn) { L=(LinkList)malloc(sizeof(Lnode)); L->next=NULL;//先建立一个带头结点的单链表; for(i=n;i>0;--i){ p=(LinkList)malloc(sizeof(Lnode));//生成新结点。 Scanf(&p->data); p->next=L->next; L->next=p; } }//CreateList_L 算法2.12归并La和Lb得到单链表LC; voidMergeList_L(LinkList&La,LinkList&Lb,LinkList&Lc) { pa=la->next; pb=lb->next; Lc=pc=La; While(pa&&pb){ If(pa_>data<=pb->data){ Pc->next=pa;pc=pa;pa=pa->next; } else{pc->next=pb;pc=pb;pb=pb->next;} } pc->next=pa? pa: pb free(Lb); }//MergeList_L 算法2.13线性表的静态单链表存储结构 // #defineMaXSIZE1000//链表的最大长度 typedefstruct{ ElemTypedata; Intcur; }component,SlinkList[MAXSize]; 算法2.13在静态链表中实现的定位函数LocateElem: intLocateElem_Sl(SlinkListS,ElemTypee) { i=s[0].cur; while(i&&s[i].data! e) i=s[i].cur; returnI; }//LocateElem_SL 算法2.14将整个数组空间初始化成一个链表: voidInitSpace_Sl(SlinkList&Space){ //将一维数组Space中各分量链成一个备用链表,space[0].cur为头指针, for(i=0;i space[i].cur=i+1; space[MAXSIZE-1].cur=0; }//InitSpace_L 算法2.14从备用空间取得一个结点: intMalloc_Sl(SlinkList&space){ i=space[0].cur; if(space[0].cur)space[0].cur=space[i].cur; returnI; }//Malloc_SL 算法2.15将空闲结点回收到备用链表 voidFree_Sl(SlinkList&space,intk){ space[k].cur=space[0].cur; space[0].cur=k; }//Free_Sl 算法2.16在一维数组SPACE中建立表示集合(A-B)∪(B-A) voiddifference(SlinkList&space,int&s) {InitSpacer_SL(space); S=Malloc_SL(space); R=s; Scanf(m,n); for(j=1;j<=m;++j){ i=Malloc_SL(space); Scanf(space[i].data; Space[r].cur=I; R=I;}//for Space[r].cur=0; For(j=1;j<=n;++j){ Sacnf(b); P=s; K=space[s].cur; While(k! ==space[r].cur&&space[k].data! =b){ P=k;k=space[k].cur;}//while If(k==space[r].cur){ I=Malloc_Sl(space); Spacepi].data=b; Space[i].cur=space[r].cur; Sapce[r].cur=I; }//if else{ space[p].cur=space[k].cur; free_Sl(space,k); if(r==k)r=p; }//else }//for }//difference 2.3.2循环链表(circularlinkedlist)它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。 循环条件不是P或p->next是否为空,而是它们是否等于头指针。 2.3.3双向链表(doublelinkedlist)在双向链表的结点中有两个指针域,其一指向直接后继,另一个指向直接前趋 线性表的双向链表存储结构: typedestructDuLNode{ ElemTypedata; StructDuLNode*prior; StructDuLNode*next; }DuLNode,*DuLinkList; 存在d->next->prior=d->prior->next=d 在双向链表中的插入和删除时有很大的不同, 算法2.18在带头结点的双链循环线性表L中第I个位置之前插入元素E; statusListInsert_Dul(DuLinkList&l,intI,ElemTypee){ //I的合法值为1<=i<=表长+1。 if(! (p=GetElemp_Dul(L,i))) returnError; s->data=e; s->prior=p->prior; p->prior->next=s; s->next=p; p->prior=s; returnok; }//ListInert_Dul 算法2.19在带头结点的双链循环线性表L中删除第i个元素E,i的合法值为1 StatusListDelete_Dul(DulinkList&L,intI,ElemType&e) { if(! (p=GetElemp_Dul(L,i))) returnError; e=p->data; p->prior->next=p->next; p->next->prior=p->prior; free(p); returnok; }//ListDelete_Dul 链表在窨的合理利用上和插入、删除时不需要移动等的优点,因此在很多场合,它是线性表的首选存储结构。 定义线性链表和基本操作: 一个带头结点的线性链表类型定义 结点类型 typedefstructLnode{//结点类型 ElemTypedata; StructLnode*next; }*link,*position; 链表类型: typedefstruct{ linkhead,tail; intlen;//元素个数 }linklist; 基本操作: statusMakeNode(Link&p,ElemTypee); voidFreeNode(Link&p); StatusInitList(LinkList&L); StatusDestroyList(LinkList&L); StatusClearList(LinkList&L); StatusInsFirst(linkh,links); StatusDelFirst(Linkh,Links); StatusAppend(LinkList&L,links); StatusRemove(LinkList&L,Link&q); StatusInsBefore(LinkList&L,Link&p,Links); StatusInsAfter(LinkList&L,Link&p,Links); StatusSetCurElem(Link&p,ElemTypee); ElemTypeGetCurElem(Linkp); StatusListEmpty(LinkListL); IntListLength(LinkListL); PositionGetHead(LinkListL); PositionGetLast(LinkListL); PositionPriorpos(LinkListl,linkp); PositionNextpos(LinkListL,linkp); StatusLocatePos(LinkListL,intI,link&p); PositionLocateElem(LinkListL,Elemtypee,status(*compare)(ElemType,ElemType)); StatusListTraverse(LinkListL,Status(*visit)()); 算法2.20在带头结点的单链线性表L的第I个元素之前插入元素e StatusListInsert_L(LinkList&L,intI,ElemTypee) {if(! LocatePos(L,i-1,h))returnERRor; if(! MakeNode(s,e))returnERROr; InsFirst(h,s); Returnok; }//ListInsert_L 算法2.21归并单链线性表LA和LB,得到LC单链线性表 StatusMergeList_L(LinkList&La,LinkList&Lb,LINkLIst&Lc,int(*compare)(ElemType,ElemType)) {//已知单链线性表LA和LB的元素按值非递减排列。 //归并LA和LB得到新的单链线表LC,LC的元素也按值非递减非列。 If(! InitList(LC))returnError;//存储空间分配失败 Ha=GetHead(La);hb=GetHead(LB); Pa=nextPos(La,ha);pb=Nextpos(lc,hb); While(pa&&pb){ A=getcurElem(pa);b=GetcurElem(pb); If((*compare)(a,b)<=0){//a<=b DelFirst(ha,q);Append(LC,q);pa=Nextpos(La,ha);} Else{//a>b DelFirst(hb,q);Append(Lc,q);pb=NextPos(Lb,hb);} }//while if(pa)Append(Lc,pa); elseAppend(Lc,pb); FreeNode(ha);FreeNode(hb); Returnok; }//MergeList_L 2.4一元多项式的表示及相加: 抽象数据类型一元多项式的定义如下: ADTpolynomial{ 数据对象: D={ai|ai∈Termset,i=1,2,…..,m,m>=0} 数据关系: R1={ CreatPolyn(&p,m) DestroyPolyn(&p) printfPolyn(p) PolynLength(p) AddPolyn(&pa,&pb) SubtractPoln(&pa,&pb) MultiplyPolyn(&pa,&pb) }AdtPolynomial StatusLocateElem(linkListl,ElemTypee,Position&q,int(*compare)(ElemType,ElemType)); StatusorderInsert(linkList&l,ElemTypee,int(*compare)(ElemType,ElemType)); 例2.4抽象数据类型polynomial的实现: typedefstruct{ floatcoef; intexpn; }term,ElemType; typedefLinkListpolynomial;//用带表头结点的有序表表示多项式。 基本操作: voidCreatPolyn(polynomail&p,intm); voidDestroyPolyn(polynomail&p); voidPrintPolYn(polynomailp); voidAddPolyn(polynomail&pa,polynomail&pb); voidSubtractPolyn(polynomail&pa,polyNomail&pb); voidMultiplyPolyn(polynomail&pa,polynomail&pb); 基本操作部分描述: intcmp(terma,termb); voidcreatPolyn(polynomail&p,intm){ InitList(p);h=GetHead(p0; e.coef=0.0;e.expn=-1;SetcurElem(h,e); for(i=1;i<=m;++i) { scanf(e.coef,e.expn); if(! LocaeElem(p,e,q,(*cmp)())) if(MakdeNode(s,e))InsFirst(q,s); } } }//creatpolyn 多项式加法: pa=pa+pb, voidAddPolyn(polynomial&pa,polynomial&pb_ ha=Gethead(pa); hb=GetHead(pb); qa=NextPos(pa,ha); qb=Nextpos(pb,hb); while(qa&&qb) { a=GetcurElem(qa);b=GetCurElem(qb); switch(*cmp(a,b)){ case-1:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构