题目
输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。
思路1
首先分析合并两个链表的过程,从合并两个链表的头结点开始,链表1的头结点的值小于链表2的头结点的值,因此链表1的头结点将是合并后链表的头结点,如图所示:
继续合并两个链表中剩余的结点。在两个链表中剩下的结点依然是排序的,因此合并这两个链表的步骤和前面的步骤是一样的。还是比较两个头结点的值,此时链表2的头结点的值小于链表1的头结点的值,因此链表2的头结点的值将是合并剩余结点得到的链表的头结点。然后把这个结点和前面合并链表时得到的链表的尾节点链接起来。当得到两个链表中值较小的头结点并把它链接到已经合并的链表之后,两个链表剩余的结点依然是排序的,因此合并的步骤和之前的步骤是一样的,这是典型的递归的过程,因此可以定义递归函数完成这一合并过程。
在本题中一旦输入空的链表就会引入空的指针,因此要对空链表单独处理。当第一个链表是空链表,也就是它的头结点是一个空指针时,那么把它和第二个链表合并,合并后就是第二个链表。同样,当输入的第二个链表的头结点是空指针的时候,那把它和第一个链表合并得到的结果就是第一个链表。如果两个链表都是空链表,合并的结果是得到一个空链表。
public ListNode Merge(ListNode pHead1,ListNode pHead2){
if(pHead1 == null)
return pHead2;
else if(pHead2 == null)
return pHead1;
ListNode pMergedHead = null;
if(pHead1.data <pHead2.data){
pMergedHead = pHead1;
pMergedHead.next = Merge(pHead1.next ,pHead2);
}else{
pMergedHead = pHead2;
pMergedHead.next = Merge(pHead1,pHead2.next);
}
return pMergedHead;
}
思路2
非递归的解法显然就是归并排序的过程
public ListNode Merge(ListNode list1,ListNode list2) {
if(list1 == null)
return list2;
if(list2 == null )
return list1;
ListNode tmp1 = list1;
ListNode tmp2 = list2;
//这里不能把返回链表赋值为null,因为下一行马上就要把它赋值给另一链表,得让它在内存里有位置才行
ListNode head = new ListNode(0);
ListNode headptr = head;
while(tmp1 != null && tmp2!=null){
if(tmp1.val <= tmp2.val)
{
head.next=tmp1;
head = head.next;
tmp1 = tmp1.next;
}else{
head.next=tmp2;
head = head.next;
tmp2=tmp2.next;
}
}
//其中一个链表已经跑到头之后,继续单链表的合并
while(tmp1 != null){
head.next = tmp1;
head = head.next;
tmp1= tmp1.next;
}
while(tmp2 != null){
head.next = tmp2;
head = head.next;
tmp2= tmp2.next;
}
head = headptr.next;
return head;
}