数据结构线性链表.docx
《数据结构线性链表.docx》由会员分享,可在线阅读,更多相关《数据结构线性链表.docx(11页珍藏版)》请在冰豆网上搜索。
![数据结构线性链表.docx](https://file1.bdocx.com/fileroot1/2023-1/9/15536935-e8c9-4f5a-8a5d-100e1c12e267/15536935-e8c9-4f5a-8a5d-100e1c12e2671.gif)
数据结构线性链表
《数据结构与算法分析》
课程实验报告
项目名称:
线性链表的操作
学生姓名:
学生学号:
指导教师:
完成日期:
【实验目的】
1.理解线性表的链式存储原理。
2.掌握链表的常用操作算法。
【实验内容】
1.创建链表并对其进行输出;
2.利用指针实现对两个线形链表的合并,并输出其结果。
【实验方式】
个人实验。
【实验设备与环境】
PC机,WindowsXP操作系统,VC++6.0开发环境
【数据结构及函数定义】
以下给出的只是范例,请同学们根据自己编写的程序内容进行填写
(1)类的定义:
类的数据成员,成员函数
classlink表类
{//数据成员
public:
intelement;节点值
link*next;指向表中下一节点的指针
//成员函数
link(constint&elemval,link*nextval=NULL)构造函数1
{element=elemval;next=nextval;}给定节点值
link(link*nextval=NULL)构造函数2
{next=nextval;}
~link(){}析构函数
(2)主函数main()实现初始化操作,完成对子函数的调用
(3)子函数
link*creat()创建链表
voidprintlist(link*lp)输出链表
link*comb(link*la,link*lb)合并链表
【测试数据与实验结果】
测试数据:
la=2356lb=4578
实验结果:
链表la(2.3.5.6)与链表(4.5.7.8)合并后得到链表(2.3.4.5.6.7.8)
【源程序清单】
(请附上源程序)
#include
usingnamespacestd;
/*单链表节点*/
structnode
{
intvalue;
node*next;
};
/*给单链表添加节点*/
voidinsertNode(node*head,intvalue)
{
node*p=head->next;
if(p==NULL)
{
p=newnode;
p->value=value;
p->next=NULL;
head->next=p;
return;
}
while(p->next!
=NULL)
{
p=p->next;
}
node*tmp=newnode;
tmp->value=value;
tmp->next=NULL;
p->next=tmp;
}
/*遍历输出链表节点*/
voidprint(node*head)
{
node*p=head->next;
while(p!
=NULL)
{
cout<value<<"";
p=p->next;
}
cout<}
/*利用一般的方法进行合并,形成整体递增有序*/
node*formalMerge(node*headA,node*headB)
{
node*head=newnode;
head->next=NULL;
node*p=headA->next;
node*q=headB->next;
if(p==NULL)
{
returnheadB;
}
if(q==NULL)
{
returnheadA;
}
while((p!
=NULL)&&(q!
=NULL))
{
if(p->value==q->value)
{
insertNode(head,p->value);
insertNode(head,q->value);
p=p->next;
q=q->next;
}
elseif(p->valuevalue)
{
insertNode(head,p->value);
p=p->next;
}
elseif(p->value>q->value)
{
insertNode(head,q->value);
q=q->next;
}
}
while(p!
=NULL)
{
insertNode(head,p->value);
p=p->next;
}
while(q!
=NULL)
{
insertNode(head,q->value);
q=q->next;
}
returnhead;
}
/*下面实现不使用任何库函数,利用交换的方法在原空间实现整体有序。
方法是先确定哪一个链表
的第一个节点的值小,把这个链表的头结点作为合并后链表的头结点,然后比较2个有序链表的当前节点
的值,如果代表最后合并链表的值小,则不用交换,否则把两个值交换,最后合并链表始终保持两个值中
的小值。
另一个链表由于交换了一个元素,当前元素可能影响该链表的有序递增,对其进行调整使其保持
递增有序,然后重复上述动作,直到一个链表遍历结束,然后把剩余的链表连接起来就行。
*/
/*调整链表的第一个节点,使其变成递增有序*/
voidchg2sort(node*head,node*&p)
{
if(head->next==NULL)//没有节点,直接返回
{
return;
}
node*s=head;
while(s->next!
=p)//s指向p的前一个节点
{
s=s->next;
}
//下面的一段找到第一个大于p节点值的节点
node*q=p;
node*r=q;
while(q!
=NULL)
{
if(q->value<=p->value)
{
r=q;//r始终指向q的前一个节点
q=q->next;
}
else
{
break;
}
}
//下面调整指针,其实可以统一写出来,为了阅读清晰把q为NULL和非NULL分开写出来
if(q==NULL)
{
r->next=p;
s->next=p->next;
p->next=NULL;
}
elseif(q!
=NULL)
{
s->next=p->next;
r->next=p;
p->next=q;
}
//由于链表进行了调换,当前链表指针也需要改变
p=s->next;
}
/*两个有序链表进行合并*/
node*merge(node*head1,node*head2)
{
node*head;//合并后的头指针
node*p=head1->next;
node*q=head2->next;
//有一个链表为空的情况,直接返回另一个链表
if(p==NULL)
{
head=head2;
returnhead;
}
elseif(q==NULL)
{
head=head1;
returnhead;
}
//两个都不为空,先确定哪个链表作为合并后的链表
if((p!
=NULL)&&(q!
=NULL))
{
if(p->valuevalue)
{
head=head1;
}
else
{
head=head2;
}
}
node*p_prior;//始终指向p节点的前一个节点
node*q_prior;
while((p!
=NULL)&&(q!
=NULL))
{
if(p->valuevalue)
{
if(head==head1)
{
p_prior=p;
p=p->next;
}
elseif(head==head2)
{
//进行当前节点值的交换
inttmp=p->value;
p->value=q->value;
q->value=tmp;
chg2sort(head1,p);//交换元素后的调整
q_prior=q;
q=q->next;
}
}
elseif(p->value==q->value)
{
p_prior=p;
p=p->next;
q_prior=q;
q=q->next;
}
elseif(p->value>q->value)
{
if(head==head1)
{
inttmp=p->value;
p->value=q->value;
q->value=tmp;
chg2sort(head2,q);
p_prior=p;
p=p->next;
}
elseif(head==head2)
{
q_prior=q;
q=q->next;
}
}
}
if(p!
=NULL)
{
q_prior->next=p;
}
if(q!
=NULL)
{
p_prior->next=q;
}
returnhead;
}
voidmain()
{
/*建立有序链表A*/
inta[5]={1,3,5,7,9};
inti;
node*headA=newnode;
headA->next=NULL;
for(i=0;i<5;++i)
{
insertNode(headA,a[i]);
}
print(headA);
/*建立有序链表B*/
intb[5]={2,4,6,8,10};
node*headB=newnode;
headB->next=NULL;
for(i=0;i<5;++i)
{
insertNode(headB,b[i]);
}
print(headB);
/*利用简单合并的方法合并成整体有序*/
node*head=formalMerge(headA,headB);
print(head);
}
【测试数据与实验结果】
上课纪律(20%)
实验过程及结果(40%)
实验报告质量(40%)
总分:
教师签字: