将两个非递减的有序链表合并为一个非递增的有序链表。要求结果链表仍使用原来两个链表的存储空间, 不另外占用其它的存储空间。表中允许有重复的数据,并输出每一步从哪取下了什么元素
完整代码如下:
#include<stdio.h>
#include<stdlib.h>
typedef struct link{ //定义链表
int data;
struct link *next;
}link;
link * initLink(int n){ //初始化链表,确定长度,输入数据
link *p,*q;
printf("依次输入数据:");
for(int i=1;i<=n;i++){
link *temp=(link*)malloc(sizeof(link)); //动态分配内存
scanf("%d",&temp->data); //填充数据
temp->next=NULL; //最后一个节点指针NULL
if(i==1){
q=temp; //给q,p赋值第一个结点
p=temp;
}
else{ //形成一条p链
p->next=temp; //p陆续指向后边的结点
p=p->next; //p移动到最后
}
}
return q;
}
link * mergeList(link *a,link *b){ //合并两条传入的链表
link *o,*p,*q; //这里p中转,o指向最后一个元素,q指向最新元素
int i=1; //第一次合并使用
while (a||b){
if(!a){ //a空了,直接指向b的结点
printf("从b取下%d\n",b->data);
p=b;
b=b->next;
} //b空了或者a的数据<=b的数据时,指向a的结点
else if(!b||a->data<=b->data){
printf("从a取下%d\n",a->data);
p=a;
a=a->next;
} //此处可和上面的合并
else {
printf("从b取下%d\n",b->data);
p=b;
b=b->next;
}
if(i==1){
o=q=p; //初始化指针
i++; //使用一次舍弃
}
else {
p->next=q; //使取下的结点连上合并后的链
q=p; //更新q的位置到最新结点
}
}
o->next=NULL; //使最后一个指向NULL输出结束条件
free(b); //a,b,q的空间可以释放
free(a);
return q;
}
int main(){
int m,n; //记录a,b的长度
printf("第一个链表的长度:");
scanf("%d",&m);
link *a = initLink(m); //初始化a
printf("第二个链表的长度:");
scanf("%d",&n);
link *b = initLink(n); //初始化b
link *c = mergeList(a,b);//合并a,b
printf("合并链(非递增):");
while(c){
printf("%d ",c->data);
c=c->next;
}
return 0;
}
--------------------------------------------------分隔线------------------------------------------
由于最近数据结构课布置了这个作业,并且知识一知半解(练习少了),所以百度找了一些代码看,然后搞了七八个小时弄出来下面的代码
#include<stdio.h>
#include<stdlib.h>
typedef struct link{ //定义链表
int data;
struct link *next;
}link;
link * initLink(int n){ //初始化链表,确定长度,输入数据
link *p,*q;
printf("依次输入数据:");
for(int i=1;i<=n;i++){
link *temp=(link*)malloc(sizeof(link)); //动态分配内存
scanf("%d",&temp->data); //填充数据
temp->next=NULL; //最后一个节点指针NULL
if(i==1){
q=temp; //给q,p赋值第一个结点
p=temp;
}
else{ //形成一条p链
p->next=temp; //p陆续指向后边的结点
p=p->next; //p移动到最后
}
}
return q;
}
link * mergeList(link *a,link *b){ //合并两条传入的链表
link *p,*q; //p指向合并链表第一个元素
q=(link*)malloc(sizeof(link)); //q:使合并链的最后一个元素为NULL
q->next=NULL;
int i=1;
while (a||b){
if(!a){ //a空了,直接指向b的结点
printf("从b取下%d\n",b->data);
p=b;
b=b->next;
} //b空了或者a的数据<=b的数据时,指向a的结点
else if(!b||a->data<=b->data){
printf("从a取下%d\n",a->data);
p=a;
a=a->next;
}
else {
printf("从b取下%d\n",b->data);
p=b;
b=b->next;
}
p->next=q->next; //使取下的结点连上合并后的链
q->next=p; //更新合并后的链
}
free(b); //a,b,q的空间可以释放
free(a);
return p;
}
int main(){
int m,n; //记录a,b的长度
printf("第一个链表的长度:");
scanf("%d",&m);
link *a = initLink(m); //初始化a
printf("第二个链表的长度:");
scanf("%d",&n);
link *b = initLink(n); //初始化b
link *c = mergeList(a,b);//合并a,b
printf("合并链(非递增):");
while(c){
printf("%d ",c->data);
c=c->next;
}
return 0;
}
可是有一个地方我一直觉得有问题(由于基础不扎实),合并链表中我觉得好像不符合题意:不另外占用其它的存储空间。
这里给q分配空间我也不太知道违背题意没,但不太放心,于是我把mergeList函数做了一些修改(可以对比上面的代码):
link * mergeList(link *a,link *b){ //合并两条传入的链表
link *p,*q; //p指向合并链表第一个元素
//q=(link*)malloc(sizeof(link)); //q:使合并链的最后一个元素为NULL
//q->next=NULL;
int i=1; //第一次合并使用
while (a||b){
if(!a){ //a空了,直接指向b的结点
printf("从b取下%d\n",b->data);
p=b;
b=b->next;
} //b空了或者a的数据<=b的数据时,指向a的结点
else if(!b||a->data<=b->data){
printf("从a取下%d\n",a->data);
p=a;
a=a->next;
} //此处可和上面的合并
/* else if(a->data<=b->data){
printf("从a取下%d\n",a->data);
p=a;
a=a->next;
} //b的数据<a的数据时,指向b的结点(不可与!a合并
*/ else {
printf("从b取下%d\n",b->data);
p=b;
b=b->next;
}
if(i==1){
q=p;
q->next=p;
i++; //使用一次舍弃
}
else {
p->next=q->next; //使取下的结点连上合并后的链
q->next=p; //更新合并后的链
}
}
free(b); //a,b,q的空间可以释放
free(a);
free(q);
return p;
}
但是有问题,就是第一个元素的合并有一些问题,输出的是一些乱码
代码总体上不够完善,如果有大佬有好的建议或者可以解决后面这个问题欢迎指导。
(@ο@)
终于实现了不占用其他存储空间了,之前的代码确实不符合题意
所以更新代码为(只需要更换mergeList函数的代码)如下:
link * mergeList(link *a,link *b){ //合并两条传入的链表
link *o,*p,*q; //这里p中转,o指向最后一个元素,q指向最新元素
int i=1; //第一次合并使用
while (a||b){
if(!a){ //a空了,直接指向b的结点
printf("从b取下%d\n",b->data);
p=b;
b=b->next;
} //b空了或者a的数据<=b的数据时,指向a的结点
else if(!b||a->data<=b->data){
printf("从a取下%d\n",a->data);
p=a;
a=a->next;
} //此处可和上面的合并
else {
printf("从b取下%d\n",b->data);
p=b;
b=b->next;
}
if(i==1){
o=q=p; //初始化指针
i++; //使用一次舍弃
}
else {
p->next=q; //使取下的结点连上合并后的链
q=p; //更新q的位置到最新结点
}
}
o->next=NULL; //使最后一个指向NULL输出结束条件
free(b); //a,b,q的空间可以释放
free(a);
return q;
}
唉,一个题搞了可能有十多个小时,被指针的引用弄得晕头转向,逻辑思维不行,以后得训练训练。望各位学好数学(真心觉得数学不好太吃亏了),不然容易绕圈转,浪费太多时间。