版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2.1线性表及其逻辑结构第2章线性表2.2线性表的顺序存储结构2.3线性表的链式存储结构2.4线性表的应用2.5有序表1/332.3.3双链表在线性表的链式存储结构中,每个物理结点增加一个指向后继结点的指针域和一个指向前驱结点的指针域
双链表。2/33线性表(a1,a2,…,ai,…,an)映射逻辑结构存储结构带头结点双链表示意图a1an∧…L2.3.3双链表3/33从任一结点出发可以快速找到其前驱结点和后继结点;从任一结点出发可以访问其他结点。双链表的优点:a1an∧…L2.3.3双链表4/33typedefstructDNode
//双链表结点类型{ElemTypedata;
structDNode*prior;
//指向前驱结点
structDNode*next;
//指向后继结点}DLinkNode;
双链表:采用类似于单链表的类型定义,其结点类型DLinkNode声明如下:2.3.3双链表5/33abc…ps操作语句:
s->next=p->next
p->next->prior=s
s->prior=p
p->next=s
在p结点之后插入结点s…(1)双链表插入结点操作插入完毕p结点next的修改尽可能放在后面执行2.3.3双链表6/33abcp操作语句:
p->next->next->prior=p
p->next=p->next->next…
删除p结点之后的一个结点(2)双链表删除结点操作删除完毕2.3.3双链表7/33
整体建立双链表也有两种方法:头插法和尾插法。与单链表的建表算法相似,主要是插入和删除的不同。1、建立双链表2.3.3双链表8/33voidCreateListF(DLinkNode*&L,ElemTypea[],intn){DLinkNode*s;inti;
L=(DLinkNode*)malloc(sizeof(DLinkNode));//创建头结点
L->prior=L->next=NULL; //前后指针域置为NULL
for(i=0;i<n;i++) //循环建立数据结点
{ s=(DLinkNode*)malloc(sizeof(DLinkNode)); s->data=a[i]; //创建数据结点s
s->next=L->next;
//将s插入到头结点之后
if(L->next!=NULL)
//若L存在数据结点,修改前驱指针
L->next->prior=s;L->next=s;
s->prior=L;
}}头插法:由含有n个元素的数组a创建带头结点的双链表L。∧L∧ais插入2.3.3双链表9/33voidCreateListR(DLinkNode*&L,ElemTypea[],intn){DLinkNode*s,*r;
inti;
L=(DLinkNode*)malloc(sizeof(DLinkNode));//创建头结点
r=L;
//r始终指向尾结点,开始时指向头结点
for(i=0;i<n;i++)
//循环建立数据结点
{s=(DLinkNode*)malloc(sizeof(DLinkNode));
s->data=a[i];
//创建数据结点s
r->next=s;s->prir=r;
//将s插入r之后
r=s;
//r指向尾结点
}
r->next=NULL;
//尾结点next域置为NULL}尾插法:由含有n个元素的数组a创建带头结点的双链表L。ais插入Lr2.3.3双链表10/332、线性表基本运算在双链表中的实现和单链表相比,双链表主要是插入和删除运算不同。boolListInsert(DLinkNode*&L,inti,ElemTypee){intj=0;DLinkNode*p=L,*s;
//p指向头结点,j设置为0
while(j<i-1&&p!=NULL) //查找第i-1个结点
{j++;
p=p->next;
}
双链表的插入算法:查找第i-1个结点p2.3.3双链表11/33if(p==NULL)
//未找到第i-1个结点,返回falsereturnfalse;
else
//找到第i-1个结点p,在其后插入新结点s
{ s=(DLinkNode*)malloc(sizeof(DLinkNode)); s->data=e; //创建新结点s s->next=p->next; //在p之后插入s结点
if(p->next!=NULL) //若存在后继结点,修改其前驱指针
p->next->prior=s; s->prior=p; p->next=s; returntrue;
}}新建结点s,将其插入到p结点之后另外解法:在双链表中,可以查找第i个结点,并在它前面插入新结点。2.3.3双链表12/33boolListDelete(DLinkNode*&L,inti,ElemType&e){intj=0;DLinkNode*p=L,*q;
//p指向头结点,j设置为0while(j<i-1&&p!=NULL)
//查找第i-1个结点
{j++;
p=p->next;
}
双链表的删除算法:查找第i-1个结点p2.3.3双链表13/33if(p==NULL)
//未找到第i-1个结点
returnfalse;
else
//找到第i-1个结点p
{ q=p->next; //q指向第i个结点
if(q==NULL)
//当不存在第i个结点时返回false
returnfalse; e=q->data; p->next=q->next;
//从双单链表中删除q结点
if(q->next!=NULL)
//若q结点存在后继结点
q->next->prior=p; //修改q结点后继结点的前驱指针 free(q);
//释放q结点
returntrue;
}}删除q结点并释放其空间另外解法:在双链表中,可以查找第i个结点,并将它删除。2.3.3双链表14/33
【例2.9】
有一个带头结点的双链表L,设计一个算法将其所有元素逆置,即第1个元素变为最后一个元素,第2个元素变为倒数第2个元素,…,最后一个元素变为第1个元素。a1Lp…3、双链表的应用示例采用头插法建表。解2.3.3双链表15/33voidreverse(DLinkNode*&L)
//双链表结点逆置{DLinkNode*p=L->next,*q;
//p指向开始结点
L->next=NULL;
//构造只有头结点的双链表L
while(p!=NULL)
//扫描L的数据结点
{ q=p->next;
//用q保存其后继结点
p->next=L->next;
//采用头插法将p结点插入
if(L->next!=NULL)
//修改其前驱指针
L->next->prior=p; L->next=p; p->prior=L; p=q;
//让p重新指向其后继结点
}}q∧La1p…a2插入2.3.3双链表16/33
【例2.10】有一个带头结点的双链表L(至少有一个数据结点),设计一个算法使其元素递增有序排列。L∧∧p……pre…有序双链表17/33voidsort(DLinkNode*&L) //双链表结点递增排序{DLinkNode*p,*pre,*q;p=L->next->next; //p指向L的第2个数据结点L->next->next=NULL; //构造只含一个数据结点的有序表while(p!=NULL){q=p->next; //q保存p结点后继结点pre=L; //从L开头比较,pre指向插入结点p的前驱结点while(pre->next!=NULL&&pre->next->data<p->data)pre=pre->next; //在有序表中找插入结点的前驱结点prep->next=pre->next; //在pre结点之后插入结点pif(pre->next!=NULL)pre->next->prior=p;pre->next=p;p->prior=pre;p=q; //扫描原双链表余下的结点}}2.3.3双链表18/33循环链表是另一种形式的链式存储结构形式。
2.3.4循环链表循环单链表:将表中尾结点的指针域改为指向表头结点,整个链表形成一个环。由此从表中任一结点出发均可找到链表中其他结点。循环双链表:形成两个环。结点类型与非循环单链表的相同结点类型与非循环双链表的相同19/33线性表(a1,a2,…,ai,…,an)映射逻辑结构存储结构a1a2an…L带头结点循环单链表示意图1、循环单链表2.3.4循环链表20/33链表中没有空指针域p所指结点为尾结点的条件:p->next==L与非循环单链表相比,循环单链表:a1a2an…Lp2.3.4循环链表21/33
某线性表最常用的操作是在尾元素之后插入一个元素和删除第一个元素,故采用()存储方式最节省运算时间。A.单链表B.仅有头结点指针的循环单链表C.双链表
D.仅有尾结点指针的循环单链表示例2.3.4循环链表22/33D.仅有尾结点指针的循环单链表a1a2an…L在尾元素之后插入一个元素删除第一个元素时间复杂度均为O(1)选择D2.3.4循环链表23/33
【例2.11】有一个带头结点的循环单链表L,设计一个算法统计其data域值为x的结点个数。intcount(LinkNode*L,ElemTypex){intcnt=0;LinkNode*p=L->next; //p指向首结点,cnt置为0while(p!=L) //扫描循环单链表L{if(p->data==x) cnt++; //找到值为x的结点后cnt增1p=p->next; //p指向下一个结点}returncnt; //返回值为x的结点个数}解2.3.4循环链表24/33线性表(a1,a2,…,ai,…,an)映射逻辑结构存储结构a1a2an…L带头结点循环双链表示意图2、循环双链表2.3.4循环链表25/33链表中没有空指针域p所指结点为尾结点的条件:p->next==L一步操作即L->prior可以找到尾结点与非循环双链表相比,循环双链表:La1a2an…p2.3.4循环链表26/33如果对含有n(n>1)个元素的线性表的运算只有4种,即删除第一个元素、删除尾元素、在第一个元素前面插入新元素、在尾元素的后面插入新元素,则最好使用()。A.只有尾结点指针没有头结点的循环单链表B.只有尾结点指针没有头结点的非循环双链表C.只有首结点指针没有尾结点指针的循环双链表D.既有头指针也有尾指针的循环单链表示例2.3.4循环链表27/33a1a2an…LC.只有首结点指针没有尾结点指针的循环双链表删除第一个元素删除尾元素在第一个元素前面插入新元素在尾元素的后面插入新元素时间复杂度均为O(1)选择C2.3.4循环链表28/33
【例2.12】有一个带头结点的循环双链表L,设计一个算法删除第一个data域值为x的结点。在双链表L中找到第一个data域值为x的结点p通过修改结点p的前后结点的指针删除结点p2.3.4循环链表29/33booldelelem(DLinkNode*&L,ElemTypex){DLinkNode*p=L->next; //p指向首结点while(p!=L&&p->data!=x) //查找第一个data值为x的结点pp=p->next;if(p!=L) //找到了第一个值为x的结点p{p->next->prior=p->prior; //删除p结点p->prior->next=p->next;free(p);returntrue; //返回真}else //没有找到为x
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 护理说课精彩瞬间
- 护理核心知识回顾
- 护理安全用药基本原则
- 呼吸系统疾病护理多学科合作大赛
- 护理员压力管理与应对
- 护理培训基地申报的注意事项
- 护理安全警示教育的培训效果
- 护理实践反思:总结经验教训
- 口腔设备学测试题及答案
- 2026医院安检面试题及答案
- 接收抵债资产管理办法
- 湖北省中小学生命安全教育课程标准(实验)
- 回收公司财务管理制度
- 房屋安全鉴定服务投标方案(技术标)
- 2025年益阳市数学五下期末学业水平测试试题含答案
- 《冰心诀》全文及解释
- 准石家庄新能力科技有限公司年产1800吨XPE发泡制品项目环境影响报告表
- JJG 455-2000工作测力仪行业标准
- 医院总值班培训课件
- 2024年青海西部机场集团青海机场有限公司招聘笔试参考题库含答案解析
- 《免疫抑制剂汇总》课件
评论
0/150
提交评论