数据结构实验二单链表基本操作题目和源程序.docx
《数据结构实验二单链表基本操作题目和源程序.docx》由会员分享,可在线阅读,更多相关《数据结构实验二单链表基本操作题目和源程序.docx(13页珍藏版)》请在冰豆网上搜索。
数据结构实验二单链表基本操作题目和源程序
实验2:
单链表基本操作
一、实验目的
1.学会定义单链表的结点类型,实现对单链表的一些基本操作和具体的函数定义,了解并掌握单链表的类定义以及成员函数的定义与调用。
2.掌握单链表基本操作及两个有序表归并、单链表逆置等操作的实现。
二、实验要求
1.预习C语言中结构体的定义与基本操作方法。
2.对单链表的每个基本操作用单独的函数实现。
3.编写完整程序完成下面的实验内容并上机运行。
4.整理并上交实验报告。
三、实验内容
1.编写程序完成单链表的下列基本操作:
(1)初始化单链表La。
(2)在La中第i个元素之前插入一个新结点。
(3)删除La中的第i个元素结点。
(4)在La中查找某结点并返回其位置。
(5)打印输出La中的结点元素值。
2.构造两个带有表头结点的有序单链表La、Lb,编写程序实现将La、Lb合并成一个有序单链表Lc。
合并思想是:
程序需要3个指针:
pa、pb、pc,其中pa,pb分别指向La表与Lb表中当前待比较插入的结点,pc指向Lc表中当前最后一个结点。
依次扫描La和Lb中的元素,比较当前元素的值,将较小者链接到*pc之后,如此重复直到La或Lb结束为止,再将另一个链表余下的内容链接到pc所指的结点之后。
3.构造一个单链表L,其头结点指针为head,编写程序实现将L逆置。
(即最后一个结点变成第一个结点,原来倒数第二个结点变成第二个结点,如此等等。
)
四、思考与提高
1.如果上面实验内容2中合并的表内不允许有重复的数据该如何操作?
2.如何将一个带头结点的单链表La分解成两个同样结构的单链表Lb,Lc,使得Lb中只含La表中奇数结点,Lc中含有La表的偶数结点?
/*----------------------------------------
*02_单链表.cpp--单链表基本操作
*对单链表的每个基本操作都用单独的函数来实现
*水上飘2009年写
----------------------------------------*/
//ds02.cpp:
定义控制台应用程序的入口点。
//
#include"stdafx.h"
#include
#include
#include
usingnamespacestd;
typedefintElemType;
typedefstructLNode{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
//确保输入的数据正确
intOncemore()
{
intn;
cout<<"输入错误,请重新输入:
";
cin>>n;
cout<if(n<=2)
n=Oncemore();
returnn;
}
//初始化单链表L
voidInitList(LinkList&L)
{
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
}
//逆位序创建一个带头结点的单链线性表
LinkListCreateList(LinkList&L,intn)
{
LinkListp;
for(inti=0;i{
p=(LinkList)malloc(sizeof(LNode));
p->data=(int)(rand()%100);//给新生成的结点随机赋一个值
p->next=L->next;L->next=p;//插入到表头
}
returnL;
}
//在L中第i个元素之前插入一个新结点
voidInsert(LinkList&L,inti)
{
LNode*p;
LNode*p1;
intm;
p1=L->next;
p=(LinkList)malloc(sizeof(LNode));
p->data=(int)(rand()%100);//给新生成的结点随机赋一个值
for(m=2;m
p1=p1->next;
if(m==i)
{
p->next=p1->next;
p1->next=p;
cout<<"在L中第i个元素之前插入一个新结点成功.";
}
elsecout<<"在L中第i个元素之前插入一个新结点失败.";
}
//删除La中的第i个元素结点
voidDelete(LinkList&L,intj)
{
LNode*p;
LNode*p1;
intm;
p1=L->next;
for(m=1;m{
p1=p1->next;
if(m==(j-2))
p=p1;//p指向欲删除结点的前一个结点
}
if(m==j)
{
p->next=p1->next;//p结点指向欲删除结点的下一个结点
deletep1;
cout<<"删除L中的第j个元素结点成功.";
}
elsecout<<"删除La中的第j个元素结点失败.";
}
//在L中查找某结点并返回其值
intLookup(LinkList&L,intk)
{
LNode*p;
p=L->next;
inti;
for(i=1;ip=p->next;
if(i==k)
{
cout<<"在L中查找第i个结点并返回其值成功.";
returnp->data;
}
else
{
cout<<"在L中查找i个结点并返回其值失败.";
return0;
}
}
/*LinkListmix(LinkList&L)
{
LinkListp1,p2,p3;
p1=L->next;
p2=L->next;
p3=L->next;
while(p1->next!
=NULL)
{
if(p1->data>p1->next->data)
p2=p1->next;
p1=p1->next;
}
if(p3->next=NULL)
{
L->next=NULL;
returnp1;
}
else
{
p3=L->next;
while(p3->next!
=p2&&!
p3->next)
p3=p3->next;
p3->next=p2->next;
p2->next=NULL;
returnp2;
}
}
voidUnion(LinkList&La,LinkList&Lb,LinkList&Lc)
{
LinkListpa,pb,pc;
pc=Lc;
while(La->next!
=NULL&&Lb->next!
=NULL)
{
pa=mix(La);
pb=mix(Lb);
if(pa->datadata)
{
pc->next=pa;
pc=pa;
}
else
{
pc->next=pb;
pc=pb;
}
}
if(La->next!
=NULL)
pc->next=La->next;
if(Lb->next!
=NULL)
pc->next=Lb->next;
}*/
//使线性表按值非递减排列
voidNotdegression(LinkList&L,intn)
{
intm;
LinkListpa;
while(n)
{
pa=L->next;
while(pa->next)//当pa不为最后一个结点
{
if(pa->data>pa->next->data)//交换两个结点的值
{
m=pa->data;
pa->data=pa->next->data;
pa->next->data=m;
pa=pa->next;//移向下一个结点
}
else
{
pa=pa->next;//移向下一个结点
continue;
}
}
n--;
}
}
//归并La和Lb,得到元素也按非递减排列的Lc
voidMerger(LinkList&La,LinkList&Lb,LinkList&Lc)
{
Lc=(LinkList)malloc(sizeof(LNode));
LinkListpa,pb,pc;
pa=La->next;
pb=Lb->next;
Lc->next=NULL;//初始化
pc=Lc;
while(pa&&pb)//当pa或pb没有到最后一个结点
{
if(pa->datadata)//pa结点插入到Lc表的末端
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
{//pb结点插入到Lc表的末端
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
pc->next=pa?
pa:
pb;/*判断La表和Lb表是否已插入完,
若没有,则剩下的插入到Lc的末端*/
deleteLa;
deleteLb;//释放头结点
}
//将L逆置(即最后一个结点变成第一个结点,原来倒数第二个结点变成第二个结点,如此等等。
)
voidCutBack(LinkList&L)
{
LinkListp1,p2,p3;
p1=L->next;
p3=L;
while(p1->next)//p1指向最后一个结点,p3指向倒数第二个结点
{
p1=p1->next;
p3=p3->next;
}
p2=p1;//p2指向最后一个结点
while(p3!
=L)//实现倒置
{
p2->next=p3;
p3->next=NULL;
p2=L->next;//指向第一个结点
p3=L;//指向头结点
while(p2->next)//p2指向新表的最后一个结点,p3指向倒数第二个结点
{
p2=p2->next;
p3=p3->next;
}
}
p2->next=NULL;//让新表最后一个结点指向空
p3->next=p1;//让p3即L头结点指向新表的第一个结点
}
//输出单链表L
voidOutputList(LinkList&L)
{
cout<LNode*L1;
inti=0;
L1=L->next;//L1指向第一个结点
while(L1->next!
=NULL)
{
cout<data;
L1=L1->next;
i++;
if(i%5==0)
cout<}
cout<data;//输出最后一个结点的值
cout<}
//第一题
voidFirstTitle()
{
cout<<"第一题开始:
"<LinkListL;
intn;
cout<<"输入表的元素个数:
";
cin>>n;
if(n<=2)
n=Oncemore();
InitList(L);
CreateList(L,n);
OutputList(L);
inti,j;
cout<<"输入插入的位置:
";
cin>>i;
Insert(L,i);
OutputList(L);
cout<<"输入删除的位置:
";
cin>>j;
Delete(L,j);
OutputList(L);
intk,m;
cout<<"输入要查找的结点的序号:
";
cin>>k;
m=Lookup(L,k);
cout<"<}
//第二题
voidSecondTitle()
{
cout<<"第二题开始:
"<LinkListLa,Lb,Lc;
inta,b;
cout<<"输入La的元素个数:
";
cin>>a;
InitList(La);
CreateList(La,a);
OutputList(La);
cout<<"输入Lb的元素个数:
";
cin>>b;
InitList(Lb);
CreateList(Lb,b);
OutputList(Lb);
//Union(La,Lb,Lc);//第二题的第二种方法
Notdegression(La,a);
cout<<"La按非递减排序后:
"<OutputList(La);
Notdegression(Lb,b);
cout<<"Lb按非递减排序后:
"<OutputList(Lb);
Merger(La,Lb,Lc);
cout<<"最后结果:
"<OutputList(Lc);
}
//第三题
voidThirdTitle()
{
cout<<"第三题开始:
"<LinkListL;
inta;
cout<<"输入L的元素个数:
";
cin>>a;
InitList(L);
CreateList(L,a);
OutputList(L);
CutBack(L);
cout<<"改变后的链表为:
"<OutputList(L);
}
voidmain()
{
srand(time(NULL));
FirstTitle();
cout<<"---------------------------------------------------"<SecondTitle();
cout<<"---------------------------------------------------"<ThirdTitle();
}