原题链接:[编程入门]链表合并
解题思路:
直接创建两个不带有哨兵结点的链表保存数据,连接后对结点进行冒泡排序,最后输出排序好的链表,思路非常直接。
注意事项:
因为没有哨兵结点,我做的时候没有考虑到交换头结点时,首指针依然指向原来的头结点,而实际上若头结点与次结点交换了顺序,首指针会依然指向原来的头结点即现在的次结点,从而导致错误。下面是实现代码。
参考代码:
#include<stdio.h>
#include<stdlib.h>
struct link{ //结点结构体
int num,mark;
struct link *pre,*next;
};
int main(){
int n,m,i,flag=1;
scanf("%d%d",&n,&m);
struct link *a,*b,*p,*q,*pp,*qn,*head; //head指针为连接a,b后的首指针
a=(struct link*)malloc(sizeof(struct link));
b=(struct link*)malloc(sizeof(struct link));
a->pre=b->pre=NULL; //初始化a,b的首指针的前序结点指针为NULL
//我自己规定每条链表的头结点的前序指针和尾结点的后序指针皆为NULL
/*创建a链表*/
p=a;
for(i=0;i<n;i++){
scanf("%d%d",&p->num,&p->mark);
if(i<n-1){
q=(struct link*)malloc(sizeof(struct link));
p->next=q;
q->pre=p;
p=q;
}
else
p->next=NULL;
}
/*创建b链表*/
p=b;
for(i=0;i<m;i++){
scanf("%d%d",&p->num,&p->mark);
if(i<m-1){
q=(struct link*)malloc(sizeof(struct link));
p->next=q;
q->pre=p;
p=q;
}
else
p->next=NULL;
}
/*因为没有哨兵结点,所以需要判断a,b链表里有没有结点,
因为创建链表时我先创建了一个无实际值的结点,
如果n,m有一个为0,我就需要把那个0个结点的链表剔除掉,
否则会将一个无实际值的结点纳入到连接后的链表中,
从而产生错误
下面是进行判断*/
if(n!=0&&m!=0){
head=p=a;
while(p->next)
p=p->next;
p->next=b;
b->pre=p;
}
else
if(n==0&&m==0){
free(a); //不能忘记从堆区释放申请来的内存空间
free(b); //不能忘记从堆区释放申请来的内存空间
return 0;
}
else
if(n==0){
free(a); //不能忘记从堆区释放申请来的内存空间
head=b;
}
else{
free(b); //不能忘记从堆区释放申请来的内存空间
head=a;
}
/*使用冒泡排序法进行排序操作*/
while(flag){
flag=0;
p=head;
while(p->next){
if(p->num>p->next->num){
q=p->next; //直接使用四个指针分别指向四个连续的结点
pp=p->pre; //等于是四个结点直接重新连一下
qn=q->next; //不然只使用一个俩个指针头容易晕
if(pp)
pp->next=q;
else //!!!如果头结点参与了交换,那么就要重新把head指针指向新的头结点
head=q;
q->pre=pp;
if(qn)
qn->pre=p;
p->next=qn;
q->next=p;
p->pre=q;
p=q;
flag=1;
}
p=p->next;
}
}
/*输出排序后链表并释放内存空间*/
p=head;
while(p){
printf("%d %d\n",p->num,p->mark);
q=p;
p=p->next;
free(q);
}
}0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复