题目:
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
解答:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1,struct ListNode* l2)
{
if(l1==NULL)
{
return l2;
}
if(l2==NULL)
{
return l1;
}
struct ListNode* newNode;
struct ListNode* tail;
if(l1->val<l2->val)
{
newNode=l1;
l1=l1->next;
}
else
{
newNode=l2;
l2=l2->next;
}
tail=newNode;
while(l1&&l2)
{
if(l1->val<l2->val)
{
tail->next=l1;
l1=l1->next;
}
else
{
tail->next=l2;
l2=l2->next;
}
tail=tail->next;
}
if(l1)
tail->next=l1;
else if(l2)
tail->next=l2;
return newNode;
}
解题思路:
①首先判断两个链表是否为空,若有一个表为空,则返回另外一个。
if(l1==NULL)
{
return l2;
}
if(l2==NULL)
{
return l1;
}
②取出两个链表中的第一个元素,对比大小,小元素的放在前面节点,
if(l1->val<l2->val)
{
newNode=l1;
l1=l1->next;
}
else
{
newNode=l2;
l2=l2->next;
}
tail=newNode;
③取小元素的下一个对比另一个链表中的元素
while(l1&&l2)
{
if(l1->val<l2->val)
{
tail->next=l1;
l1=l1->next;
}
else
{
tail->next=l2;
l2=l2->next;
}
tail=tail->next;
}
④当任意一个链表为空时,另外一个非空链表的最后一个元素设置为最末节点
if(l1)
tail->next=l1;
else if(l2)
tail->next=l2;
return newNode;
完整代码可以如下:
#include<stdio.h>
#include<stdlib.h>
#define LEN sizeof(struct ListNode)//定义长度
//定义一个struct listnode型的结点
struct ListNode
{
int val;//存放链表数据
struct ListNode *next;//存放下一节点的地址
};
int n;
struct ListNode* mergeTwoLists(struct ListNode* l1,struct ListNode* l2)
{
/*判断两个链表是否为空,如果为空则返回另外一个*/
if(l1==NULL)
{
do
{
printf("%d\t",l2->val);
l1=l1->next;
}while(l2!=NULL);
return l2;
}
if(l2==NULL)
{
do
{
printf("%d\t",l1->val);
l2=l2->next;
}while(l1!=NULL);
return l1;
}
//定义新结点,来存放新的链表
struct ListNode* newNode;
struct ListNode* tail;
/*取出两个链表中的第一个元素,对比大小,小元素的放在前面节点*/
if(l1->val<l2->val)
{
newNode=l1;
l1=l1->next;
}
else
{
newNode=l2;
l2=l2->next;
}
/*将tail设置为新链表的头结点*/
tail=newNode;
while(l1&&l2)//当两个链表不为空时取小元素的下一个对比另一个链表中的元素
{
if(l1->val<l2->val)
{
tail->next=l1;
l1=l1->next;
}
else
{
tail->next=l2;
l2=l2->next;
}
tail=tail->next;
}
/*当任意一个链表为空时,另外一个非空链表的最后一个元素设置为最末节点*/
if(l1)
tail->next=l1;
else if(l2)
tail->next=l2;
/返回并输出最终结点
do
{
printf("%d\t",newNode->val);
newNode=newNode->next;
}while(newNode!=NULL);
return newNode;
}
//动态建立链表
struct ListNode* creat()
{
struct ListNode *head;
struct ListNode *p1,*p2;
p1=p2=(struct ListNode*)malloc(LEN);
n=0;
scanf("%d",&p1->val);
head=NULL;
while(p1->val!=0)
{
n=n+1;
if(n==1)
head=p1;
else
p2->next=p1;
p2=p1;
p1=(struct ListNode*)malloc(LEN);
scanf("%d",&p1->val);
}
p2->next=NULL;
return(head);
}
//输出链表
void print(struct ListNode *head)
{
struct ListNode *p;
p=head;
if(head!=NULL)
do
{
printf("%d",p->val);
p=p->next;
}while(p!=NULL);
printf("\n");
}
void main()
{
struct ListNode *q1,*q2;
printf("please input q1:\n");
q1=creat();
printf("q1:\n");
print(q1);
printf("please input q2:\n");
q2=creat();
printf("q2:\n");
print(q2);
printf("\n");
mergeTwoLists(q1,q2);
}
注意:
①动态链表的建立:
int n;
struct ListNode* creat()
{
struct ListNode *head;
struct ListNode *p1,*p2;
p1=p2=(struct ListNode*)malloc(LEN);
n=0;
scanf("%d",&p1->val);
head=NULL;
while(p1->val!=0)//当p1->不为0时
{
n=n+1;
if(n==1)//n=1时,让head=p1,head指向新开辟的结点
head=p1;
else
p2->next=p1;//当n>1将p1的值赋给p2->next
p2=p1;//接着使p1=p2
p1=(struct ListNode*)malloc(LEN);//开辟一个新的空间使p1指向它
scanf("%d",&p1->val);
}
p2->next=NULL;
return(head);//返回头结点
}