两个有序链表的合并
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《数据结构》实验报告
班级:JS001001 姓名:周卫华学号:2010300028E-mail:****************
◎实验题目: 将两个带头结点的有序循环链表合并成一个带头结点的有序循环链表
◎实验目的:1.掌握使用visual c++6.0上机调试程序的基本方法。
2.掌握线性表的链式存储结构-循环链表的定义及C语言实现。
3.掌握线性表在链式存储结构-循环链表中的基本操作如将两个循环链表合并为一个循环链表的操作。
◎实验内容:设A与B分别为两个带有头结点的有序循环链表(所谓有序是指链接点按数据域值大小链接,本题不妨设按数据域值从小到大排列),list1和list2分别为指向两个链表的头指针。将这两个链表合并为一个带头结点的有序循环链表。
一、需求分析
本程序需要实现将两个有序循环链表合成一个有序循环链表的功能,即对这个程序输入两个有序循环链表,该程序输出一个有序循环链表。对于输入的两个循环链表要求是必须是有序非递减的,如1,2,3,5,7符合输入条件,但是3,5,4,7,2,9则不符合输入条件。输入值可以是任意实数。输出的有序循环链表依赖于输入的两个有序循环链表。如输入的两个链表为1,3,4,6,8;2,5,7,9则输出的链表为1,2,3,4,5,6,7,8,9.上面展示了输入正确时的预期输出,当输入不正确时则不能得到正确的输出,如输入1,3,5,4,6;2,5,3,7时输出为1,2,3,5,4,5,3,6,7显然不正确。
二、概要设计
按照题意,本程序中使用单向循环链表作为存储结构,每一个节点为结构体类型,存放数据和下一个节点的地址。基本流程如下:定义三个该结构体类型的指针变量list1,list2,head;期中list1,list2用来构造存放输入数据的两个循环链表的头指针,head 用来作为生成的第三个循环链表的头指针。接下来主函数调用creat()函数并手工输入数据构成两个待合并链表。然后调用print()函数用来打印list1,list2来验证构造的链表正确。链表构造完成后调用mergell()函数来合并list1,list2并存放在head中,最后把head打印出来。本程序主要模块有:主程序模块,构造链表并输入数据模块,打印输出链表模块,合并链表模块。
三、详细设计
1.元素类型,节点类型和指针类型:
元素类型:int num;int lista=0,listb=0;
节点类型: struct list
{
int num;
struct list *next;
};
指针类型:struct list *head,*end;struct list *pa,*pb,*pc; struct list
*list1,*list2,;
2.每个模块的分析:
(1)主程序模块:
int main() //主函数
printf(" 欢迎使用将两个有序循环链表合并成一个有序循环链表程序");
struct list*list1,*list2,*head;//定义三个struct list类型的指针变量 list1=(struct list *)malloc(sizeof(struct list));
list2=(struct list *)malloc(sizeof(struct list));
head=(struct list *)malloc(sizeof(struct list));//为list1,list2,head 申请空间
printf("\n请按从小到大的顺序输入第一组有序循环链表,以0结束\n"); list1=creat(); //调用创建链表的函数
printf("输入的这组链表是:\n");
print(list1); //打印第一个链表
printf("\n\n请按从小到大的顺序输入第二组有序循环链表,以0结束\n"); list2=creat(); //调用创建链表的函数
printf("输入的这组链表是:\n");
print(list2); //打印第二个循环链表
mergell (list1,list2,head) ; //调用合并两个链表的函数
printf("\n\n合并后的有序循环链表为:\n");
print(head->next);//打印合并后的循环链表
return 0;
}
(2)构造链表并输入每个数据模块:
struct list *creat() //定义创建链表的函数
{
struct list*p=NULL;
struct list*q=NULL; //定义两个活动指针变量
head=NULL;
int num;
scanf("%d",&num);
while(num!=0)
{
p=(struct list *)malloc(sizeof (struct list)); //开辟空间
p->num=num;
if(head==NULL)
head=p;
else
q->next=p;
q=p;
scanf("%d",&num);
}
end=q; //将链表的结尾最后一个结点赋给end
end->next=head; //让最后一个结点的的下个结点的地址不为空而指向头指针
return(head); //返回新建链表的头指针
}
(3)打印已经构造完成的链表模块
void print(struct list*head) //定义打印循环链表的函数
{
struct list*r=head; //定义活动指针变量以输出各节点数据
do
{
printf("%d ",r->num);
r=r->next;
}while(r!=head); //当活动指针重新指向头结点时,循环结束}
(4)合并两个有序循环链表模块
struct list *mergell(struct list *la,struct list *lb,struct list * lc) //定义合并函数
{
struct list *pa,*pb,*pc; //定义三个活动指针变量分别指向la,lb,lc
int lista=0,listb=0;
pc=lc;
pa=la;
pb=lb; //为pa,pb,pc赋值
while(((pa!=la)||(lista==0))&&((pb!=lb)||(listb==0)))//使用while循环语句
{
if(pa->num<=pb->num)
{
pc->next=pa;
pc=pa;
pa=pa->next;
lista=1;
}
else
{
pc=pb;
pb=pb->next;
listb=1;
}
}
if(pa!=la) //如果lb数据已经完成排序而la还有数据未排,则把la未排数据插入到lc后面
{
while(pa!=la)