时间限制: 1Sec 内存限制: 128MB
已有a、b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号升序排列。
输入
第一行,a、b两个链表元素的数量N、M,用空格隔开。 接下来N行是a的数据 然后M行是b的数据 每行数据由学号和成绩两部分组成
输出
按照学号升序排列的数据
样例输入
2 3
5 100
6 89
3 82
4 95
2 10
样例输出
2 10
3 82
4 95
5 100
6 89
这道题的本质是使用链表进行排序
分为五个步骤:
#include
#include
typedef struct LNode{
int no;
int grade;
struct LNode* next;
}*LinkList;
int main()
{
int n,m,i,j;
scanf("%d %d", &n,&m);
LinkList L1,L2,p,q,r,r1,r2;
L1=(LinkList)malloc(sizeof(struct LNode));
r1=L1; L1->next=NULL;
for(i=0;i<n;i++){//input L1
p=(LinkList)malloc(sizeof(struct LNode));
scanf("%d%d", &p->no,&p->grade);
r1->next=p;
r1=p;
}
r1->next=NULL;
L2=(LinkList)malloc(sizeof(struct LNode));
r2=L2;
for(i=0;i<m;i++){//input L2
p=(LinkList)malloc(sizeof(struct LNode));
scanf("%d%d", &p->no,&p->grade);
r2->next=p;
r2=p;
}
r2->next=NULL;
r1->next=L2->next; //connect L1,L2
for(i=0;i<m+n;i++) {
q=L1; p=L1->next; r=p->next;
for(j=0;j<m+n-i-1;j++){
if(p->no>r->no){
q->next=r;
p->next=r->next;
r->next=p;
q=r;
r=p->next;
}
else{
q=p;
p=r;
r=r->next;
}
}
}
p=L1->next;
while(p){
printf("%d %d\n", p->no,p->grade);
p=p->next;
}
return 0;
}
在这道题中,我遇到的最大问题是如何去解决链表排序。而链表排序在我看来最好的办法是冒泡排序,因为只有冒泡排序紧密涉及到两个相邻元素的交换问题。
但是在进行排序的过程中,我遇到了很大的问题,就是出现排序出错,问题代码如下:
for(i=0;i<m+n;i++){
q=L1; p=L1->next; r=p->next;
for(j=0;j<m+n-i-1;j++) {
if(p->no>r->no){
q->next=r;
p->next=r->next;
r->next=p;
}
q=p;
p=r;
r=r->next;
}
}
如果不是按照思路查找代码,很难发现这处错误。
错误的原因是将交换链表中的两个元素和对原链表进行下一次循环的初始化的操作等同。
对三个指针p,q,r
,现在要交换q,r
。
一开始的关系为:q=p->next; r=q->next;
交换后的关系为:r=p->next,; q=r->next;
未交换的调整操作为:p=q; q=r; r=r->next;
交换后的调整操作应为:p=r; r=q->next
显然两者并不是等同的。
for(i=0;i<m+n;i++){
q=L1; p=L1->next; r=p->next;
for(j=0;j<m+n-i-1;j++) {
if(p->no>r->no){
q->next=r;
p->next=r->next;
r->next=p;
q=r;
r=p->next;
}
else{
q=p;
p=r;
r=r->next;
}
}
}