2-3 链表拼接
本题要求实现一个合并两个有序链表的简单函数。链表结点定义如下:
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
思路:
和2-1的求多项式和思路大致一样,创建head来保存头指针的值,tmp在每个循环中将该保存的数据保存在tmp结点中,prior用来连接每个tmp结点;注意判断循环结束的标准应该是指针为NULL,而不是像我最开始一样,憨的以为-1是每个链表的最后一个值,用data != -1作为标准。按照这个算法,最后返回的指针应该是head->next,而不是head.
AC代码:
struct ListNode *head = NULL,*tmp,*prior;
prior = (struct ListNode*)malloc(sizeof(struct ListNode));
head = prior; //保存头指针的值,结束时返回
while(list1 != NULL && list2 != NULL){
tmp = (struct ListNode*)malloc(sizeof(struct ListNode));
if(list1->data < list2->data){
tmp->data = list1->data;
list1 = list1->next;
}
else{
tmp->data = list2->data;
list2 = list2->next;
}
prior->next = tmp;
prior = tmp;
}
if(list1)
prior->next = list1;
if(list2)
prior->next = list2;
return head->next; //head后的第一个结点是空的,head->next为实际头指针
}
写完后觉得tmp结点创建的意义不大,每个循环中都要多分配一次结点空间,不如直接使用prior连接原list1、list2链表,既省空间又减少了时间,所以做出了如下的改进。
改进后的代码
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2){
struct ListNode *head = NULL,*prior;
prior = (struct ListNode*)malloc(sizeof(struct ListNode));
head = prior;
while(list1 != NULL && list2 != NULL){
if(list1->data < list2->data){
prior->next = list1;
list1 = list1->next;
prior = prior->next;
}
else{
prior->next = list2;
list2 = list2->next;
prior = prior->next;
}
}
if(list1)
prior->next = list1;
if(list2)
prior->next = list2;
head = head->next; //head后的第一个结点是空的,head->next为实际头指针
return head;
}