数据结构实例精讲链表文档格式.docx

上传人:b****6 文档编号:20373728 上传时间:2023-01-22 格式:DOCX 页数:77 大小:83.91KB
下载 相关 举报
数据结构实例精讲链表文档格式.docx_第1页
第1页 / 共77页
数据结构实例精讲链表文档格式.docx_第2页
第2页 / 共77页
数据结构实例精讲链表文档格式.docx_第3页
第3页 / 共77页
数据结构实例精讲链表文档格式.docx_第4页
第4页 / 共77页
数据结构实例精讲链表文档格式.docx_第5页
第5页 / 共77页
点击查看更多>>
下载资源
资源描述

数据结构实例精讲链表文档格式.docx

《数据结构实例精讲链表文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构实例精讲链表文档格式.docx(77页珍藏版)》请在冰豆网上搜索。

数据结构实例精讲链表文档格式.docx

如果输入的数据为指定的结束标志,转到⑦;

⑤若是空表,将新结点链接到表头;

若是非空表,将新结点链接到表尾;

⑥转到③;

⑦返回头指针。

采用倒挂法的步骤与正挂法差不多,只是插入新结点时,总是将其插入到表头。

(2)源程序。

#include<

iostream>

usingnamespacestd;

typedefintElemType;

structLNode

{ElemTypedata;

LNode*next;

};

typedefLNode*LinkList;

LinkListcreate();

LinkListcreate1();

voidprint(LinkListL);

voidDestroyList(LinkList&

L);

intmain()

{

LinkListL;

cout<

<

"

输入链表中的数据,以-1作为结束:

endl;

L=create();

cout<

采用正挂法建立的单链表为:

print(L);

DestroyList(L);

L=create1();

采用倒挂法建立的单链表为:

return0;

LinkListcreate()//采用正挂的方法建立不带头结点的单链表

LinkListp1,p2,head;

intnum;

head=NULL;

//创建一个空表

cin>

>

num;

while(num!

=-1)//如果输入的数据为指定的结束标志,结束

{

p1=newLNode;

//利用new运算符向系统申请分配一个结点

p1->

data=num;

next=NULL;

if(head==NULL)

head=p1;

//若是空表,将新结点链接到表头

else

p2->

next=p1;

//若是非空表,将新结点链接到表尾

p2=p1;

}

returnhead;

//返回头指针

LinkListcreate1()//采用倒挂的方法建立不带头结点的单链表

LinkListp,head;

=-1)

p=newLNode;

p->

next=head;

head=p;

//插入到表头

voidprint(LinkListL)

LinkListp;

p=L;

if(p==NULL)

链表是空表!

else

while(p->

next!

=NULL)

{

p->

data<

->

"

;

p=p->

next;

}

data<

endl;

L)

LinkListp=L;

while(p!

L=L->

deletep;

p=L;

(3)应用于后面实例的头文件LinkList.h和LinkList.cpp文件。

本例实现了链表的创建和输出等基本运算,为了在后面的实例中直接应用这些基本运算,将链表的定义及函数声明保存到LinkList.h头文件中,各函数的实现保存到LinkList.cpp中。

头文件LinkList.h保存内容如下:

源程序文件LinkList.cpp保存内容如下:

#include"

Linklist.h"

p1->

data;

//输入结点的数据域

while(p1->

data!

head=p1;

deletep1;

这样,在下面的实例中如果需要用到这些基本运算,只需要#include"

LinkList.h"

包含头文件即可。

2.4链表的操作实例

1.插入和删除

链表的一个重要特点是插入、删除操作灵活方便,不需移动结点,只需改变结点中指针域的值即可。

【实例2-13】链表有序插入。

编写一个函数voidInsert(LinkList&

L,ElemTypenum)在链表L中插入一个值为num的结点,插入后链表仍保持有序。

设单链表L中的结点按数据域data的值从小到大的顺序排列。

并调用所编写的有序插入函数建立一个有序链表。

在插入时,有三种情况:

①插入到一个空表中;

②插入到链表的首部;

③插入到链表中间或链表的最后。

其中,前两种情况会改变头指针。

而后一种情况,需要先在单链表中寻找到正确的插入位置(设寻找到的插入位置在第i-1个结点之后)并由指针p指示,然后通过修改指针,重新建立ai-1与num、num与ai两两数据元素之间的链,从而实现三个元素之间链接关系的变化。

num插入时指针变化如图2-2所示,图中虚线所示为插入前的指针。

图2-2单链表的插入

(2)函数程序代码。

voidInsert(LinkList&

L,ElemTypenum)

LinkListp,s;

s=newLNode;

s->

data=num;

if(p==NULL)//插入到空表

{

L=s;

s->

elseif(p->

data>

num)//插入到链表首

next=L;

else//插入到中间或最后

while(p->

next&

&

next->

num)

next=p->

next=s;

(3)函数应用的示例源程序。

L,ElemTypenum);

ElemTypenum;

L=NULL;

Insert(L,num);

cin>

采用插入法建立的有序单链表为:

【实例2-14】删除最小值。

在单链表中删除最小值结点。

若要在L为头指针的单链表中,删除数据域值最小的结点。

首先要搜索单链表以找到指定删除结点(以指针q指示)的前驱结点(以指针pre指示),然后仅需修改结点pre中的指针域,最后释放待删除结点q所占的存储空间。

图2-3显示了删除时指针变化情况,虚线所示为删除前的指针。

图2-3单链表的结点删除

一般来说,在链表中指定数据域的结点时,有四种情况要考虑:

①链表是一个空表;

②要删除的结点在链表的首部(表头指针被修改);

③要删除的结点在链表中间或最后;

④要删除的结点在链表中不存在。

单链表中删除最小值结点,为使结点删除后不出现“断链”,应知道被删结点的前驱。

而“最小值结点”是在遍历整个链表后才能知道。

所以算法应首先遍历链表,求得最小值结点及其前驱。

遍历结束后再执行删除操作。

将“在单链表中删除最小值结点”这一操作写成一个函数DeleteMin。

函数体中,用指针p来遍历单链表,用指针q指向最小值结点,指针pre指向最小值结点q的前驱结点。

voidDeleteMin(LinkList&

//L是不带头结点的单链表,算法删除其最小值结点。

LinkListp,pre,q;

if(L==NULL)

return;

//链表为空,无结点可删,直接返回

//p为工作指针,指向待处理的结点。

此时链表非空。

pre=NULL;

//pre用于指向最小值结点的前驱

q=p;

//q指向最小值结点,初始假定第1个结点是最小值结点

next!

if(p->

q->

data)//查最小值结点

{

pre=p;

q=p->

}

//p指针后移。

if(pre==NULL)

L=L->

next;

//头结点是最小值结点

pre->

next=q->

//最小值结点不是头结点

deleteq;

//释放最小值结点空间

链表初始情况为:

DeleteMin(L);

删除最小值后,链表为:

}voidDeleteMin(LinkList&

通常可以在线性链表的第一个结点之前附设一个结点,称之为头结点。

头结点的数据域可以不存储任何信息,也可存储如线性表的长度等附加信息,头结点的指针域存储指向第一个结点的指针,而链表的头指针指向头结点。

这样,在第一个结点前面插入新结点和删除第一个结点就不影响表头指针L的值(如上面算法就引起了头指针L的变化),而只改变头结点的指针域的值,因此就可以和其他位置的插入、删除同样处理了。

例如,若L为带头结点的单链表,则插入函数Insert可简单地写成:

{//L是带头结点的递增有序单链表,插入num后仍保持有序

在双向链表中,若p是指向表中某个结点的指针,则有

p==p->

prior==p->

prior->

next

双向链表的插入和删除算法与单链表有很大的不同,需同时修改两个方向上的指针。

例如,在双向链表中指针p所指的结点之前插入元素x的操作步骤为:

s=newDuLNode;

s->

data=x;

prior=p->

prior;

next=s;

next=p;

prior=s;

删除双向链表中指针p所指的结点的操作步骤为:

next=p->

deletep;

【实例2-15】删除重复结点。

编写一个函数,删除不带头结点的单链表L中的重复结点。

用指针p来遍历单链表,p的初始值为单链表的头指针。

p指向一个数据结点时,从它的后继结点开始到表的结束,找与其值相同的结点并删除之;

然后p指向下一个结点;

依此类推,直到p指向最后结点时,遍历结束。

voidDeleteSame(LinkList&

//L是不带头结点的单链表,算法删除其重复结点。

LinkListp,q,r;

//p指向第一个结点

if(p==NULL)

return;

next)

while(q->

next)//从p的后继开始找重复结点

if(q->

data==p->

data)

r=q->

//找到重复结点,用r指向该结点,删除r

q->

next=r->

deleter;

q=q->

if(p->

=NULL)

p=p->

}

DeleteSame(L);

删除重复结点后,链表为:

【实例2-16】集合的差集。

已知两个带头结点的递增有序的单链表La、Lb分别存储集合A和B,编写一个函数求两个集合A和B的差集A=A-B(即仅由在A中出现而不在B中出现的元素所构成的集合)。

求两个集合A和B的差集A=A-B,即在A中删除A和B中共有的元素。

由于集合用单链表存储,问题变成删除链表中的结点问题。

删除结点时,要记住被删除结点的前驱,以便顺利删除被删结点。

由于两个链表递增有序,因此遍历时,两链表均从第1个结点开始,直到其中一个链表到尾为止。

voidDifference(LinkList&

La,LinkListLb)

//La和Lb是带头结点的递增有序的单链表,算法求两集合的差集A=A-B

LinkListpa,pb,pre;

pa=La->

//pa和pb分别是链表La和Lb的工作指针

pb=Lb->

pre=La;

//pre为La中pa所指结点的前驱结点的指针

while(pa!

=NULL&

pb!

if(pa->

pb->

pre=pa;

pa=pa->

//La表中当前结点指针后移

elseif(pa->

data>

pb=pb->

//Lb表中当前结点指针后移

pre->

next=pa->

//处理A、B中元素值相同的结点,应删除

deletepa;

pa=pre->

La,LinkListLb);

LinkListLa,Lb;

输入集合A中的数据,以-1作为结束:

La=newLNode;

La->

next=NULL;

Insert(La,num);

集合A初始情况为:

print(La->

next);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 少儿英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1