劍指offer——合併兩個排序的鏈表

題目:輸入兩個遞增排序的鏈表,合併這兩個鏈表並使新鏈表中的結點仍然是按照遞增排序的。鏈表的結點定義如下:

struct ListNode
{
	int val;
	ListNode* next;
};

例如輸入如圖所示的鏈表1和鏈表2,合併之後爲鏈表3:

鏈表1:

鏈表2:

鏈表3:

這是一個經常被各公司採用的面試題。在面試過程中,最容易犯的兩個錯誤是:

  1. 合併出來的鏈表要麼中間斷了,要麼並沒有做到遞增排序
  2. 程序一旦有特殊輸入就會崩潰

首先分析合併兩個鏈表的過程:

(1)鏈表1的頭結點的值小於鏈表2的頭結點的值,因此鏈表1的頭結點是合併後的鏈表的頭結點。

(2)在剩餘的結點中,鏈表2的頭結點的值小於鏈表1的頭結點的值,因此鏈表2的頭結點是剩餘結點的頭結點,把這個結點和之前已經合併好的鏈表的尾結點連接起來。

我們繼續合併兩個鏈表中剩餘的結點,在兩個鏈表中剩餘的結點依然是排序的,因此合併這兩個鏈表的步驟和前面的步驟是一樣的。這就是典型的遞歸過程,我們可以定義遞歸函數完成這一合併過程。

注意:本題一旦引入空鏈表就會引入空指針,因此我們要對空鏈表進行單獨處理。

參考代碼如下:

 ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(pHead1 == NULL)
            return pHead2;
        if(pHead2 == NULL)
            return pHead1;
        ListNode* MergeHead = NULL;
        if(pHead1->val < pHead2->val)
        {
            MergeHead = pHead1;
            MergeHead->next = Merge(pHead1->next,pHead2);
        }
        else
        {
            MergeHead = pHead2;
            MergeHead->next = Merge(pHead1,pHead2->next);
        }
        return MergeHead;
    }

發佈了78 篇原創文章 · 獲贊 98 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章