思路:这个题的主要题意思就是让你将原来有序的两个链表合并成一个有序的链表。主要是让你返回的链表有序合并成一个链表即可。怎么合并成一个链表呢?那我们就得重新创造一个新的头结点新的尾结点,既然它要让新的链表有序,我们可以两个链表从头开始比较,哪个小就要尾插到新的链表上。
这道题还有一个大坑点就是我们取下来新的节点,链到新节点的头,但头刚开始是空指针就没法链,所以我们可以先取两个链表较小的做为头结点,然后依次比较尾插到新链表中就可以了;
还有一个要注意的点就是判断极端条件,如果有一个链表为空,上面你所有的操作就会让程序访问到空指针,所以刚开始我们就要判断一下,如果一个链表为空我们就要返回另外一个。
最后一个注意点可能是万一 一个链表最终都尾插完了,而另外一个链表没有尾插完,我们就需要将这个没有尾插完的链表尾插到新链表上。
总结思路:1.刚开始要取小的作为头。
2.我们要取小的尾插到新链表中。
3.最后判断有没有尾插完的链表,如果没有尾插完的链表,就将其剩余的尾插到新的链表上。
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
//判断如果一个链表为空就返回另外一个,如果链表都为空,我们就返回空
if(list1==NULL){
return list2;
}
if(list2==NULL){
return list1;
}
if(list1==NULL&&list2==NULL){
return NULL;
}
struct ListNode* newhead ,*newtail=NULL;
//刚开始要取小的作为新的头
if(list1->val<list2->val){
newhead =newtail =list1;
list1=list1->next;
}
else{
newhead =newtail =list2;
list2=list2->next;
}
//取小的尾插
while(list1&&list2){
if(list1->val<list2->val){
newtail->next =list1;
list1=list1->next;
}
else{
newtail->next =list2;
list2=list2->next;
}
newtail =newtail->next;
}
//如果还有没有尾插完的链表,就将剩下的元素都尾插到新的链表
if(list1){
newtail->next =list1;
}
else{
newtail->next =list2;
}
return newhead;
}
当然还有一种思路就是有带哨兵位的头结点,这个带哨兵位的头结点不存储有效数据。我们有了这个哨兵位就可以把你想要的数据都链到这个头上,我们就不用像上面那样刚开始就要取小的作为头结点,直接尾插到这个哨兵位的头结点,但是这个头结点不是真正的头我们在返回新的链表的时候我们一定要返回哨兵位的头结点的next。
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
if(list1==NULL){
return list2;
}
if(list2==NULL){
return list1;
}
struct ListNode* newhead ,*newtail=NULL;
newhead =newtail =(struct ListNode*)malloc(sizeof(struct ListNode));
while(list1&&list2){
if(list1->val<list2->val){
newtail->next =list1;
list1=list1->next;
}
else{
newtail->next =list2;
list2=list2->next;
}
newtail =newtail->next;
}
if(list1){
newtail->next =list1;
}
else{
newtail->next =list2;
}
struct ListNode* realhead =newhead->next;
free(newhead);
return realhead;
}