实验3 线性表的链式存储讲解.docx

上传人:b****5 文档编号:7382609 上传时间:2023-01-23 格式:DOCX 页数:25 大小:48.37KB
下载 相关 举报
实验3 线性表的链式存储讲解.docx_第1页
第1页 / 共25页
实验3 线性表的链式存储讲解.docx_第2页
第2页 / 共25页
实验3 线性表的链式存储讲解.docx_第3页
第3页 / 共25页
实验3 线性表的链式存储讲解.docx_第4页
第4页 / 共25页
实验3 线性表的链式存储讲解.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

实验3 线性表的链式存储讲解.docx

《实验3 线性表的链式存储讲解.docx》由会员分享,可在线阅读,更多相关《实验3 线性表的链式存储讲解.docx(25页珍藏版)》请在冰豆网上搜索。

实验3 线性表的链式存储讲解.docx

实验3线性表的链式存储讲解

实验报告三线性表的链式存储

 

一、实验目的:

(1)掌握单链表的基本操作的实现方法。

(2)掌握循环单链表的基本操作实现。

(3)掌握两有序链表的归并操作算法。

二、实验内容:

(请采用模板类及模板函数实现)

1、线性表链式存储结构及基本操作算法实现

[实现提示](同时可参见教材p64-p73页的ADT描述及算法实现及ppt)函数、类名称等可自定义,部分变量请加上学号后3位。

也可自行对类中所定义的操作进行扩展。

所加载的库函数或常量定义:

(1)单链表存储结构类的定义:

templateclassLinkList;//前视定义,便于使用友元

template

classNode

{friendclassLinkList;//友元类

private:

datatypedata;

Node*next;//此处也可以省略

}

template

classLinkList

{

public:

LinkList();//建立只有头结点的空链表

LinkList(datatypea[],intn);//建立有n个元素的单链表

~LinkList(){}//析构函数,释放整个链表空间

intLength();//求单链表的长度

datatypeGet(inti);//取单链表中第i个结点的元素值

voidInsert(inti,datatypex);//在单链表中第i个位置插入元素值为x的结点

voiddestroy()//在单链表中删除所有的结点

voidPrintList();//遍历单链表,按序号依次输出各元素

intEmpty()//判断表是否为空

private:

Node*head;//单链表的头指针

};

 

(2)初始化带头结点空单链表构造函数实现

输入:

前置条件:

动作:

初始化一个带头结点的空链表

输出:

后置条件:

头指针指向头结点。

template

LinkList:

:

LinkList()

{

head=newNode;

head->next=NULL;

}

 

(3)利用数组初始化带头结点的单链表构造函数实现

输入:

已存储数据的数组及数组中元素的个数

前置条件:

动作:

利用头插或尾插法创建带头结点的单链表

输出:

后置条件:

头指针指向头结点,且数组中的元素为链表中各结点的数据成员。

template

LinkList:

:

LinkList(datatypea[],intn)

{inti;

Node*s;

head=newNode;

head->next=NULL;

for(i=0;i

{

s=newNode;

s->data=a[i];

s->next=head->next;

head->next=s;

}

}

 

(4)在带头结点单链表的第i个位置前插入元素e算法

输入:

插入位置i,待插入元素e

前置条件:

i的值要合法

动作:

在带头结点的单链表中第i个位置之前插入元素e

输出:

后置条件:

单链表中增加了一个结点

template

voidLinkList:

:

Insert(inti,datatypex)

{

Node*p;intj;

p=head;j=0;//指针p初始化

while(p&&j

{

p=p->next;//指针p后移

j++;

}//找插入点

if(!

p)

cout<<"i不合法!

";

else{

 Node*s;

s=newNode;

s->data=x;

s->next=p->next;

p->next=s;

}

}

 

(5)在带头结点单链表中删除第i个元素算法

输入:

删除第i个结点,待存放删除结点值变量e

前置条件:

单链表不空,i的值要合法

动作:

在带头结点的单链表中删除第i个结点,并返回该结点的值(由e传出)。

输出:

后置条件:

单链表中减少了一个结点

template

datatypeLinkList:

:

Delete(inti)

{if(head->next==NULL)

Cout<<”表为空,无法删除!

”;

Node*p;

intj;

p=head;j=0;

while(p&&j

{

p=p->next;

j++;

}//找到第i-1个结点

if(!

p||!

p->next)

throw“i不合法”;

else{

q=p->next;

x=q->data;

p->next=q->next;

deleteq;

returnx;

}

}

(6)遍历单链表元素算法

输入:

前置条件:

单链表不空

动作:

遍历输出单链表中的各元素。

输出:

后置条件:

template

voidLinkList:

:

PrintList()

{Node*p;

p=head->next;//p指向首结点

while(p)//p!

=NULL

{

cout<data;

cout<<””;

p=p->next;

}

}

(7)求单链表表长算法。

输入:

前置条件:

动作:

求单链表中元素个数。

输出:

返回元素个数

后置条件:

template

intLinkList:

:

Length()

{

Node*p;

p=head->next;

inti=0;

while(p)

{

p=p->next;

i++;

}

returni;

}

 

(8)判单链表表空算法

输入:

前置条件:

动作:

判表是否为空。

输出:

为空时返回1,不为空时返回0

后置条件:

template

intLinkList:

:

Length()

{if(head->next=NULL)

return1;

return0;

}

(9)获得单链表中第i个结点的值算法

输入:

前置条件:

i不空,i合法

动作:

找到第i个结点。

输出:

返回第i个结点的元素值。

后置条件:

template

datatypeLinkList:

:

Get(inti)

{

Node*p;

intj;//计数器

p=head->next;j=1;//或p=head;j=0;

while(p&&j

{

p=p->next;//工作指针p后移

j++;

}

if(!

p)

cout<<“i值不合法,超过了元素的个数!

";

elsereturnp->data;

}

 

(10)删除链表中所有结点算法(这里不是析构函数,但功能相同)

输入:

前置条件:

单链表存在

动作:

清除单链表中所有的结点。

输出:

后置条件:

头指针指向空

template

voidlinklist:

:

destroy()

{

Node*p;

while(head->next!

=NULL)

{

p=head;

head=head->next;

deletep;

}

head->next=NULL;

}

(11)上机实现以上基本操作,写出main()程序:

参考p72

voidmain()

{

inta[]={9,2,3,4,5,6},n=6;

LinkListmylist;

for(inti=0;i

mylist.Insert(i,a[i]);

cout<<"yichishuchushuju:

"<

mylist.PrintList();

cout<

cout<<"表长为:

"<

cout<

mylist.Insert(5,8);

mylist.PrintList();

cout<

cout<<"表长为:

"<

mylist.Empty();

mylist.destroy();

cout<

cout<<"表长为:

"<

}

粘贴测试数据及运行结果:

 

2、参考单链表操作定义与实现,自行完成单循环链表的类的定义与相操作操作算法。

(1)利用数组初始化带头结点的单循环链表构造函数实现

输入:

已存储数据的数组及数组中元素的个数

前置条件:

动作:

利用头插或尾插法创建带头结点的单循环链表

输出:

后置条件:

头指针指向头结点,且数组中的元素为链表中各结点的数据成员,尾指针指向头结点。

template

linklist:

:

linklist(datatypea[],intn)

{

node*s;

head=newnode;

head->next=head;

for(inti=0;i

{

s=newnode;

s->data=a[i];

s->next=head->next;

head->next=s;

}

}

(2)在带头结点单循环链表的第i个位置前插入元素e算法

输入:

插入位置i,待插入元素e

前置条件:

i的值要合法

动作:

在带头结点的单循环链表中第i个位置之前插入元素e

输出:

后置条件:

单循环链表中增加了一个结点

template

voidlinklist:

:

insert(inti,datatypeitem)

{

node*p;intj;

p=head;

j=0;//指针p初始化

while(p->next!

=head&&j

{

p=p->next;//指针p后移

j++;

}//找插入点

if(!

p)

cout<<"i不合法!

";

else

{

node*s;

s=newnode;//申请一个结点

s->data=item;//将插入元素保存在P结点中

s->next=p->next;

p->next=s;

}

}

(3)在带头结点单循环链表中删除第i个元素算法

输入:

删除第i个结点,待存放删除结点值变量e

前置条件:

单循环链表不空,i的值要合法

动作:

在带头结点的单循环链表中删除第i个结点,并返回该结点的值(由e传出)。

输出:

后置条件:

单循环链表中减少了一个结点

template

datatypelinklist:

:

Delete(inti)

{if(head->next==head)

cout<<"表为空,无法删除!

";

node*p,*q;

intj;

p=head;

j=0;

while(p->next!

=head&&j

{

p=p->next;

j++;

}

if(!

p)

cout<<"i不合法";

else{

datatypex;

q=p->next;

x=q->data;

p->next=q->next;

deleteq;

returnx;

}

}

(4)遍历单循环链表元素算法

输入:

前置条件:

单循环链表不空

动作:

遍历输出单循环链表中的各元素。

输出:

后置条件:

template

voidlinklist:

:

putlist()

{node*p;

p=head->next;//p=head;

if(p->next==head)

cout<<"表为空";

else

while(p!

=head)//p->next!

=head

{

cout<data<<"";//p=p->next;

p=p->next;//cout<data<<"";

}

}

(5)上机实现以上基本操作,写出main()程序:

voidmain()

{

inta[]={45,89,9,13,8,2},n=6;

linklists;

for(inti=0;i

s.insert(i,a[i]);

s.insert(1,14);

cout<<"第一次遍历链表元素输出:

"<

s.putlist();

s.Delete(3);

cout<<"第二次遍历表输出;"<

s.putlist();

}

粘贴测试数据及运行结果:

3、采用链式存储方式,并利用单链表类及类中所定义的算法加以实现线性表La,Lb为非递减的有序线性表,将其归并为新线性表Lc,该线性表仍有序(未考虑相同时删除一重复值)的算法。

模板函数:

#include

templateclasslinklist;//前视定义

template

classnode

{

friendclasslinklist;

private:

typedata;

node*next;

};

template

classlinklist

{

private:

node*head;

public:

linklist();//无参构造函数

linklist(typea[],intn);//有参构造函数

voidprintlist();//遍历链表

typeinsert(inti,typeitem);//在第i个结点元素前插入元素item

intlength();//求链表长度

voidsort();//对新的链表元素排序并输出

typeget(inti);//获得第i个结点元素

};

template

linklist:

:

linklist()

{

head=newnode;

head->next=NULL;

}

template

linklist:

:

linklist(typea[],intn)

{

node*s;

head=newnode;

head->next=NULL;

for(inti=0;i

{

s=newnode;

s->data=a[i];

s->next=head->next;

head->next=s;

}

}

template

typelinklist:

:

insert(inti,typeitem)

{

node*p;

intj=0;

p=head;

while(p&&j

{

p=p->next;//指针p后移

j++;

}

if(!

p)

cout<<"i不合法!

";

else

{

node*s;

s=newnode;//申请一个结点

s->data=item;//将插入元素保存在s结点中

s->next=p->next;

p->next=s;

returnitem;

}

}

template

intlinklist:

:

length()

{

node*p;

p=head;

intn=0;

while(p!

=NULL)

{

p=p->next;

n++;

}

returnn;

}

template

typelinklist:

:

get(inti)

{

node*p;

intj=0;

p=head;

while(p&&j

{

p=p->next;

j++;

}

if(!

p)

cout<<"i值不合法!

";

else

returnp->data;

}

template

voidlinklist:

:

sort()

{

node*p,*q;

typetemp;

p=head;

while(p)

{

q=p->next;

while(q)

{

if(p->data>q->data)

{

temp=p->data;

p->data=q->data;

q->data=temp;

}

q=q->next;

}

p=p->next;

}

}

template

voidlinklist:

:

printlist()

{

node*p;

p=head->next;

while(p)

{

cout<data<<"";

p=p->next;

}

}

voidmain()

{

inta[]={1,66,0,5,2,6,7};

intb[]={3,4,6,7,8,76};

linklistLa(a,7);

linklistLb(b,6);

cout<<"第一组元素输出:

";

La.printlist();

cout<

cout<<"第二组元素输出:

";

Lb.printlist();

cout<

for(inti=2;i

{

La.insert(i,Lb.get(i));//将数组a的元素插入到b当中去

}

cout<<"合并后的元素为:

"<

La.sort();//排序

La.printlist();

cout<

cout<<"合并后元素个数为:

"<

}

 

粘贴测试数据及运行结果:

选做题:

1、按一元多项式ADT的定义,实现相关操作算法:

ADTPNodeis

Data

系数(coef)

指数(exp)

指针域(next):

指向下一个结点

Operation

暂无

endADTPNode

ADTPolynomialis

Data

PNode类型的头指针。

Operation 

 Polynomail

初始化值:

 动作:

申请头结点,由头指针指向该头结点,并输入m项的系数和指数,建立一元多项式。

 DestroyPolyn

输入:

前置条件:

多项式已存在

动作:

消毁多项式。

输出:

后置条件:

头指针指向空

 PolyDisplay

输入:

前置条件:

多项式已存在,不为空

动作:

输出多项式各项系数与指数

输出:

后置条件:

AddPoly

输入:

另一个待加的多项式

前置条件:

一元多项式pa和pb已存在。

动作及后置条件:

完成多项式相加运算,(采用pa=pa+pb形式,并销毁一元多项式pb)

输出:

endADTPolynomial

2、实现一元多项式的减法,操作描述如下:

SubPoly

输入:

待减的多项式pb

前置条件:

一元多项式pa和pb已存在。

动作及后置条件:

完成多项式减法运算,即:

pa=pa-pb,并销毁一元多项式pb。

输出:

3、参考P74-P79页双向链表的存储结构定义及算法,编程实现双向链表的插入算法和删除算法。

#include

templateclasslinklist;

template

classnode

{friendclasslinklist;

private:

typedata;

node*next,*prior;

};

template

classlinklist

{

public:

linklist();//建立只有头结点的空链表

linklist(typea[],intn);//建立有n个元素的双向链表

~linklist(){}//析构函数,释放整个链表空间

intlength();//求双向链表的长度

typeinsert(inti,typex);//在双向链表中第i个位置插入元素值为x的结点

typeDelete(inti);//删除第i个位置的元素

voidprintlist();//遍历双向链表,按序号依次输出

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

当前位置:首页 > 农林牧渔 > 林学

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

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