数据结构:第2章-线性表_第1页
数据结构:第2章-线性表_第2页
数据结构:第2章-线性表_第3页
数据结构:第2章-线性表_第4页
数据结构:第2章-线性表_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

数据结构第2章线性表2.1

线性表及其抽象数据类型2.2线性表的顺序存储结构2.3线性表的链式存储结构2.6一元多项式的表示及相加2.4栈和队列2.5循环线性链表和双向链表1数据结构第2章线性表2.1线性表及其抽象数据类型

定义:线性表(LinearList)是由n(n≥0)个类型相同的数据元素a1,a2,…,an组成的有限序列,记做(a1,a2,…,ai-1,ai,ai+1,…,an)。数据元素之间是一对一的关系,即每个数据元素最多有一个直接前驱和一个直接后继。逻辑结构图:2数据结构第2章线性表特点:①同一性:线性表由同类数据元素组成,每一个ai必须属于同一数据对象。②有穷性:线性表由有限个数据元素组成,表长度就是表中数据元素的个数。③有序性:线性表中相邻数据元素之间存在着序偶关系<ai,ai+1>。2.1线性表及其抽象数据类型

3数据结构第2章线性表抽象数据类型定义:ADTLinearList{

数据元素:D={ai|ai∈D0,i=1,2,…,n;n≥0,D0为某一数据对象}

关系:S=<ai,ai+1>|ai,ai+1∈D0,i=1,2,…,n-1}

基本操作:

(1)InitList(L)

操作前提:L为未初始化线性表。操作结果:将L初始化为空表。

(2)DestroyList(L)

操作前提:线性表L已存在。操作结果:将L销毁。

………p11}ADT

LinearList返回2.1线性表及其抽象数据类型

4数据结构第2章线性表2.2线性表的顺序存储结构定义:采用顺序存储结构的线性表通常称为顺序表。假设线性表中每个元素占k个单元,第一个元素的地址为loc(a1),则第i个元素的地址为:loc(ai)=loc(a1)+(i-1)×k是指用一组地址连续的存储单元依次存储线性表中的各个元素,使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中。5数据结构第2章线性表...loc(a1)+(maxlen-1)knan

loc(a1)+(n-1)k………iai

loc(a1)+(i-1)k………2a2

Loc(a1)+(2-1)k1a1Loc(a1)逻辑地址内存空间状态存储地址顺序存储结构示意图空闲2.2线性表的顺序存储结构6数据结构第2章线性表C语言定义#definemaxsize

线性表可能达到的最大长度typedef

struct{

ElemType

elem[maxsize];

intlast;

}SeqList; 2.2线性表的顺序存储结构7数据结构第2章线性表基本运算①查找操作②插入操作③删除操作2.2线性表的顺序存储结构8数据结构第2章线性表①查找操作按序号查找GetData(L,i):要求查找线性表L中第i个数据元素,其结果是L.elem[i-1]。按内容查找Locate(L,e):要求查找线性表L中与给定值e相等的数据元素,其结果是:若在表L中找到与e相等的元素,则返回该元素在表中的序号;若找不到,则返回一个“空序号”,如-1。2.2线性表的顺序存储结构9数据结构第2章线性表按内容查找Locate(L,e):int

Locate(SeqListL,ElemTypee){ i=0;while((i<=L.last)&&(L.elem[i]!=e))i++;if(i<=L.last)return(i+1);else return(-1);}2.2线性表的顺序存储结构10数据结构第2章线性表2.2线性表的顺序存储②插入操作是指在表的第i(1≤i≤n+1)个位置,插入一个新元素e,使长度为n的线性表

(e1,…,ei-1,ei,…,en)

变成长度为n+1的线性表(e1,…,ei-1,e,ei,…,en)。例如:线性表(4,9,15,28,30,30,42,51,62),需在第4个元素之前插入一个元素“21”。则需要将第9个位置到第4个位置的元素依次后移一个位置,然后将“21”

插入到第4个位置。

(4,9,15,2128,30,30,42,51,62)

#defineOK1#defineERROR0

int

InsList(SeqList*L,int

i,ElemTypee){

intk;if((i<1)||(i>L->last+2)){printf(“插入位置i值不合法”);

return(ERROR);}if(L->last>=maxsize-1){printf(“表已满无法插入”);

return(ERROR);}

for(k=L->last;k>=i-1;k--)L->elem[k+1]=L->elem[k];

L->elem[i-1]=e;

L->last++;return(OK);}

时间复杂度:

O(n)11数据结构第2章线性表③删除操作是指将表的第i(1≤i≤n)个元素删去,使长度为n的线性表(e1,…,ei-1,ei,ei+1,…,en),变成长度为n-1的线性表(e1,…,ei-1,ei+1,…,en)。

int

DelList(SeqList*L,int

i,ElemType*e){

intk;if((i<1)||(i>L->last+1)){

printf(“删除位置不合法!”);

return(ERROR);

}*e=L->elem[i-1];

for(k=i;k<=L->last;k++)L->elem[k-1]=L->elem[k];L->last--;return(OK);}时间复杂度:O(n)2.2线性表的顺序存储结构12数据结构第2章线性表2.2线性表的顺序存储结构例2-1

:有两个顺序表LA和LB,其元素均为非递减有序排列,编写一个算法,将它们合并成一个顺序表LC,要求LC也是非递减有序排列。算法思想:设表LC是一个空表,为使LC也是非递减有序排列,可设两个指针i、j分别指向表LA和LB中的元素,若LA.elem[i]>LB.elem[j],则当前先将LB.elem[j]插入到表LC中,若LA.elem[i]≤LB.elem[j],当前先将LA.elem[i]插入到表LC中,如此进行下去,直到其中一个表被扫描完毕,然后再将未扫描完的表中剩余的所有元素放到表LC中。voidmerge(SeqList*LA,SeqList*LB,SeqList*LC){i=0;j=0;k=0;while(i<=LA->last&&j<=LB->last)if(LA->elem[i]<=LB->elem[j]){LC->elem[k]=LA->elem[i];i++;k++;}else{LC->elem[k]=LB->elem[j];j++;k++;}while(i<=LA->last){LC->elem[k]=LA->elem[i];i++;k++;}while(j<=LB->last){LC->elem[k]=LB->elem[j];j++;k++;}LC->last=LA->last+LB->last+1;}13数据结构第2章线性表优点:②可方便地随机存取表中的任一元素。缺点:①插入或删除运算不方便,除表尾的位置外,在表的其它位置上进行插入或删除操作都必须移动大量的结点,其效率较低;①无须为表示结点间的逻辑关系而增加额外的存储空间;②由于顺序表要求占用连续的存储空间,存储分配只能预先进行静态分配。因此当表长变化较大时,难以确定合适的存储规模。返回2.2线性表的顺序存储结构14数据结构第2章线性表2.3线性表的链式存储结构定义:采用链式存储结构的线性表称为链表。动态链表静态链表单链表双链表循环链表实现角度链接方式15数据结构第2章线性表单链表:链表中的每个结点只有一个指针域结点(Node):单链表包括两个域数据域:指针域:用来存储结点的数据值用来存储数据元素的直接后继的地址(或位置)头指针:指向链表头结点的指针。为了正确地表示结点间的逻辑关系,必须在存储线性表的每个数据元素值的同时,存储指示其后继结点的地址(或位置)信息,这两部分信息组成的存储映象叫做结点。2.3线性表的链式存储结构16数据结构第2章线性表单链表头指针H存储地址数据域指针域1D437B1313C119HNULL25F3731A737G1943E2531AHBCDEFGH∧2.3线性表的链式存储结构17数据结构第2章线性表单链表头结点H∧带头结点的空单链表带头结点的单链表EFGH∧H2.3线性表的链式存储结构18数据结构第2章线性表单链表存储结构描述typedef

structNode{

ElemTypedata;

structNode*next;}Node,*LinkList;2.3线性表的链式存储结构19数据结构第2章线性表单链表的基本运算①建立单链表②单链表查找③单链表插入操作④单链表删除⑤求单链表的长度2.3线性表的链式存储结构20数据结构第2章线性表①建立单链表头插法建表sA∧s指向新申请的结点s->data=A;H∧sA∧插入第一个结点:插入某一个结点:H∧A∧sB∧从一个空表开始,重复读入数据,生成新结点,将读入数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头结点之后,直至读入结束标志为止。×①s->next=H->next;②H->next=s;顺序可以颠倒吗?H∧初始化空表2.3线性表的链式存储结构21数据结构第2章线性表2.3线性表的链式存储①建立单链表头插法建表算法

Linklist

CreateFromHead(){

LinkListL;Node*s;charc;

intflag=1;L=(Linklist)malloc(sizeof(Node));

L->next=NULL;while(flag){c=getchar();if(c!=’$’){s=(Node*)malloc(sizeof(Node));s->data=c;

s->next=L->next;L->next=s;

}else flag=0;}}22数据结构第2章线性表①建立单链表尾插法建表sA∧s指向新申请的结点s->data=A;H∧sA∧插入第一个结点:插入某一个结点:sB∧将新结点插到当前单链表的表尾上。增加一个尾指针r,使之指向当前单链表的表尾。r->next=s;r=s;顺序可以颠倒吗?H∧初始化空表rrH∧A∧rr2.3线性表的链式存储结构23数据结构第2章线性表2.3线性表的链式存储②建立单链表尾插法建表算法

Linklist

CreateFromTail(){

LinkListL;Node*r,*s;

intflag=1;charc;L=(Node*)malloc(sizeof(Node));L->next=NULL;r=L;

while(flag){c=getchar();if(c!=’$’){s=(Node*)malloc(sizeof(Node));s->data=c;r->next=s;r=s;}else{flag=0;r->next=NULL;

}}}24数据结构第2章线性表②单链表查找按序号查找设带头结点的单链表的长度为n,要查找表中第i个结点,则需要从单链表的头指针L出发,从第一个结点(L->next)开始顺着链域扫描。用指针p指向当前扫描到的结点,初值指向第一个结点(p=L->next),用j做记数器,累计当前扫描过的结点数(初值为0),当j=i时,指针p所指的结点就是要找的第i个结点。

Node*Get(LinkListL,inti){Node*p;

p=L;

j=0;

while((p->next!=NULL)&&(j<i)){

p=p->next;

j++;

}if(i==j)returnp;

elsereturnNULL;

}2.3线性表的链式存储结构25数据结构第2章线性表③单链表查找按值查找指在单链表中查找是否有结点值等于e的结点,若有的话,则返回首次找到的其值为e的结点的存储位置,否则返回NULL。

查找过程从单链表的头指针指向的第一个结点出发,顺着链逐个将结点的值和给定值e作比较。

Node*Locate(LinkList

L,ElemTypekey){Node*p;p=L->next;while(p!=NULL)if(p->data!=key)

p=p->next;

elsebreak;returnp;}2.3线性表的链式存储结构26数据结构第2章线性表③单链表插入要在带头结点的单链表L中第i个数据元素之前插入一个数据元素e,需要首先在单链表中找到第i-1个结点并由指针pre指示,然后申请一个新的结点并由指针s指示,其数据域的值为e,并修改第i-1个结点的指针使其指向s,然后使s结点的指针域指向第i个结点。se∧×①s->next=pre->next;②pre->next=s;顺序可以颠倒吗?a1a2ai-1aian∧……preL2.3线性表的链式存储结构27算法实现数据结构第2章线性表2.3线性表的链式存储④单链表插入

voidInsList(LinkList

L,int

i,ElemTypee){ Node*pre,*s;

intk=0;pre=L;while(pre!=NULL&&k<i-1){pre=pre->next;k=k+1;}if(k!=i-1){

printf(“插入位置不合理!”);

return;}s=(Node*)malloc(sizeof(Node));s->data=e;

s->next=pre->next;pre->next=s;}28数据结构第2章线性表④单链表删除欲在带头结点的单链表L中删除第i个结点,则首先要通过计数方式找到第i-1个结点并使pre指向第i-1个结点,而后删除第i个结点并释放结点空间。××pre->next=pre->next->next;a1a2ai-1aian∧……preai+1rL

free(r);2.3线性表的链式存储结构29算法实现数据结构第2章线性表2.3线性表的链式存储⑤单链表删除

voidDelList(LinkList

L,int

i,ElemType*e){Node*pre,*r;pre=L;intk=0;while(pre->next!=NULL&&k<i-1){pre=pre->next;k=k+1;}if(k!=i-1){

printf(“删除结点的位置i不合理!”);returnERROR;}

r=pre->next;pre->next=pre->next->next;free(r);returnOK;}30数据结构第2章线性表⑤求单链表的长度可以采用“数”结点的方法来求出单链表的长度,用指针p依次指向各个结点,从第一个元素开始“数”,一直“数”到最后一个结点(p->next=NULL)。算法实现

int

ListLength(LinkListL){Node*p;p=L->next; j=0;while(p!=NULL){ p=p->next;j++;}returnj;}2.3线性表的链式存储结构31数据结构第2章线性表2.3线性表的链式存储结构例2-2有两个单链表LA和LB,其元素均为非递减有序排列,编写一个算法,将它们合并成一个单链表LC,要求LC也是非递减有序排列。要求:新表LC利用原表的存储空间。

LinkList

MergeLinkList(LinkList

LA,LinkListLB){Node*pa,*pb;

LinkListLC;pa=LA->next;pb=LB->next;LC=LA;LC->next=NULL;r=LC;while(pa->next!=NULL&&pb->next!=NULL){if(pa->data<=pb->data){r->next=pa;r=pa;pa=pa->next;}else{r->next=pb;r=pb;pb=pb->next;}}if(pa)r->next=pa;elser->next=pb;free(LB);return(LC);}返回32数据结构第2章线性表循环链表(CircularLinkedList):是一个首尾相接的链表。特点:将单链表最后一个结点的指针域由NULL改为指向头结点或线性表中的第一个结点,就得到了单链形式的循环链表,并称为循环单链表。在循环单链表中,表中所有结点被链在一个环上。L带头结点的空循环链表a1a2ai-1aian……L带头结点的循环单链表a1a2ai-1aian……采用尾指针的循环单链表rear2.5循环线性链表和双向链表33数据结构第2章线性表循环链表(CircularLinkedList)例2-3有两个带头结点的循环单链表LA、LB,编写一个算法,将两个循环单链表合并为一个循环单链表,其头指针为LA。先找到两个链表的尾,并分别由指针p、q指向它们,然后将第一个链表的尾与第二个表的第一个结点链接起来,并修改第二个表的尾q,使它的链域指向第一个表的头结点。a1a2ai-1aian……LAb1b2bi-1bibn……LBpq

p->next=LB->next;q->next=LA;free(LB);2.5循环线性链表和双向链表34数据结构第2章线性表循环链表(CircularLinkedList)算法实现1LinkListmerge_1(LinkListLA,LinkListLB){Node*p,*q;p=LA;q=LB;while(p->next!=LA)p=p->next; while(q->next!=LB)q=q->next;

p->next=LB->next;free(LB);

q->next=LA;

return(LA);}时间复杂度为

O(n)2.5循环线性链表和双向链表35数据结构第2章线性表循环链表(CircularLinkedList)例2-3有两个带头结点的循环单链表LA、LB,编写一个算法,将两个循环单链表合并为一个循环单链表,其头指针为LA。采用带尾指针的循环链表,执行时间可降低为O(1)。a1a2ai-1aian……RAb1b2bi-1bibn……RBpRA->next=RB->next->next;RB->next=p;free(RB->next);2.5循环线性链表和双向链表36数据结构第2章线性表循环链表(CircularLinkedList)算法实现2LinkListmerge_2(LinkListRA,LinkListRB){Node*p;

p=RA->next;RA->next=RB->next->next;

free(RB->next);RB->next=p;return(RB);}2.5循环线性链表和双向链表37数据结构第2章线性表双向链表(DoubleLinkedList)在单链表的每个结点里再增加一个指向其前趋的指针域prior。这样形成的链表中就有两条方向不同的链,我们称之为双(向)链表。结构定义:typedef

struct

Dnode{

ElemTypedata;

struct

DNode*prior,*next;}DNode, *DoubleList;datapriornext定义:2.5循环线性链表和双向链表38数据结构第2章线性表双向链表(DoubleLinkedList)示意图:L空的双向循环链表L非空的双向循环链表abc2.5循环线性链表和双向链表39数据结构第2章线性表双向链表(DoubleLinkedList)前插操作:ab……esp×①①

p->prior->next=s;②②s->prior=p->prior;顺序可以颠倒吗?×③③p->prior=s;④④s->next=p;顺序可以颠倒吗?顺序可以颠倒吗?2.5循环线性链表和双向链表40数据结构第2章线性表2.3线性表的链式存储双向链表(DoubleLinkedList)前插操作算法实现:int

DlinkIns(DoubleList

L,int

i,ElemTypee){

DNode*s,*p;

p=search(L,i);s=(DNode*)malloc(sizeof(DNode));if(s){s->data=e;

s->prior=p->prior;p->prior->next=s;s->next=p;p->prior=s;returnTRUE;}elsereturnFALSE;}41数据结构第2章线性表2.5循环线性链表和双向链表双向链表(DoubleLinkedList)删除操作:abc……p×①p->prior->next=p->next;①×②②p->next->prior=p->prior;free(p);42数据结构第2章线性表2.5循环线性链表和双向链表双向链表(DoubleLinkedList)删除操作算法实现:int

DlinkDel(DoubleList

L,inti){

DNode*p;

p=search(L,i);

p->prior->next=p->next;p->next->prior=p->prior;free(p);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论