2-3 链表拼接 (20分)
本题要求实现一个合并两个有序链表的简单函数。
链表结点定义如下:
struct ListNode {
int data;
struct ListNode *next;
};
函数接口定义:
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2);
其中list1和list2是用户传入的两个按data升序链接的链表的头指针;函数mergelists将两个链表合并成一个按data升序链接的链表,并返回结果链表的头指针。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int data;
struct ListNode *next;
};
struct ListNode *createlist(); /*裁判实现,细节不表*/
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2);
void printlist( struct ListNode *head )
{
struct ListNode *p = head;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main()
{
struct ListNode *list1, *list2;
list1 = createlist();
list2 = createlist();
list1 = mergelists(list1, list2);
printlist(list1);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
1 3 5 7 -1
2 4 6 -1
输出样例:
1 2 3 4 5 6 7
AC
常规思路,正常代码,把特殊情况全考虑了,一般情况不要出现错误,就OK的。
啊啊,借鉴了好多,最后还因为没有判断链表是否为空错误。
这是一个套路题,我又一次的做了好久没做出来!
————————————————————————————————————
有的东西真的不是一次就可以成功的,虽然上一次写了出来,还挺顺利,但是后来这一次没有做出来,啊啊啊,加油啊!
注意尾指针的使用方法,这个真的很重要,尤其是没有头节点的时候。
申请新节点
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2) {
struct ListNode *a,*b,*p,*s;
struct ListNode *L=NULL;
s=L;//s作为一个尾指针
a=list1;
b=list2;
if(a==NULL)
return b;
if(b==NULL)
return a;
while(a&&b) { //升序排列
p=(struct ListNode *)malloc(sizeof(struct ListNode));
if(a->data<b->data) {
p->data=a->data;
a=a->next;
} else {
p->data=b->data;
b=b->next;
}
p->next=NULL;
if(L==NULL)
L=p;
else
s->next=p;
s=p;
}
if(a)
s->next=a;
if(b)
s->next=b;
/*两种情况都得判断,不能一个if,一个else,
因为可能是二者都不满足条件了,同时退出*/
return L;
}
不申请新节点
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2) {
struct ListNode *a,*b,*s,*L,*p;
a=list1;
b=list2;
L=NULL;
s=L;//尾指针
if(!a&&b)
return b;
if(a&&!b)
return a;
while(a&&b) {
if(a->data<b->data) {
p=a;
a=a->next;
} else {
p=b;
b=b->next;
}
p->next=NULL;
if(L==NULL)
L=p;
else
s->next=p;
s=p;
}
if(a)
s->next=a;
if(b)
s->next=b;
return L;
}
完整的代码:
这个真的运行成功了,我太感动了,在这个题上停留两天了。
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int data;
struct ListNode *next;
};
struct ListNode *createlist() { /*裁判实现,细节不表*/
struct ListNode *L=NULL,*p,*s=NULL;//s是一个尾指针,这个真的很重要!!!置为空
int x;
scanf("%d",&x);
while(x!=-1) {
p=(struct ListNode*)malloc(sizeof(struct ListNode));
p->data=x;
p->next=NULL;
if(L==NULL)//17-21行,错了好多次,记住啊啊啊
L=p;
else
s->next=p;
s=p;
scanf("%d",&x);
}
return L;
}
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2) {
struct ListNode *a,*b,*p,*s=NULL;//s作为一个尾指针
struct ListNode *L=NULL;
a=list1;
b=list2;
if(a==NULL)
return b;
if(b==NULL)
return a;
while(a&&b) { //升序排列
p=(struct ListNode *)malloc(sizeof(struct ListNode));
if(a->data<b->data) {
p->data=a->data;
p->next=NULL;
a=a->next;
} else {
p->data=b->data;
p->next=NULL;
b=b->next;
}
if(L==NULL)//48-52,记住啊啊啊
L=p;
else
s->next=p;
s=p;
}
if(a)
s->next=a;
if(b)
s->next=b;
return L;
}
void printlist( struct ListNode *head ) { //没有头指针的链表
struct ListNode *p = head;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main() {
struct ListNode *list1, *list2;
list1 = createlist();
list2 = createlist();
list1 = mergelists(list1, list2);
printlist(list1);
return 0;
}