題目:輸入兩個遞增排列的單鏈表,合併這兩個鏈表,並使新鏈表中的節點仍然是遞增排序的。ios
首先,分析從合併兩個鏈表的頭結點開始,若是鏈表 1 的頭結點的值小於鏈表 2 的頭結點的值。所以,鏈表 1 的頭結點將是合併後鏈表的頭結點。繼續合併兩個鏈表中的剩餘節點,在兩個鏈表中,剩下的節點仍然是排序的。所以合併這兩個鏈表的過程與前面的步驟是同樣的,仍是要比較兩個頭結點的值。spa
當獲得兩個鏈表中值較小的頭結點並把它鏈接到已經合併的鏈表以後,兩個鏈表剩餘的節點仍然是排序的,這就是典型的遞歸過程。指針
接下來解決魯棒問題。每當代碼試圖訪問空指針指向的內存時程序就會崩潰,從而致使魯棒問題。在本題中一旦輸入空的鏈表指針就會引入空指針,所以,須要對空鏈表進行單獨處理。當第一個鏈表是空鏈表時(即它的頭指針爲 NULL),那麼把它和第二個鏈表合併,顯然合併的結果就是第二個鏈表。一樣,當輸入的第二個鏈表爲空時,它和第一個鏈表合併的結果也就是第一個鏈表。若是兩個鏈表都是空鏈表,則合併以後的鏈表仍然爲空鏈表。排序
//合併兩個已排序的單鏈表
#include<iostream>
using namespace std;遞歸
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}ListNode, *LinkList;內存
LinkList InitializeLinkList(ListNode *L)
{
if(L == NULL)
{
L = new ListNode();
L->next = NULL;
}
return L;
}it
void CreateLinkList(LinkList L, ElemType e)
{
if(L == NULL)
return;
ListNode *p, *s;
s = L;
while(s->next != NULL)
s = s->next;
p = new ListNode();
p->data = e;
p->next = NULL;
s->next = p;
}io
void PrintLinkList(LinkList L)
{
ListNode *p;
p = L->next;
while(p != NULL)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}stream
//遞歸合併兩個單鏈表
ListNode* MergeTwoLinkList(LinkList L1, LinkList L2)
{
if(L1 == NULL) //輸入的一個鏈表爲空時,返回另外一個鏈表的頭結點
return L2;
if(L2 == NULL)
return L1;
ListNode *head = NULL;
ListNode *p = L1;
ListNode *q = L2;List
if(p->data > q->data)
{
head = q;
head->next = MergeTwoLinkList(p, q->next);
}
else
{
head = p;
head->next = MergeTwoLinkList(p->next, q);
}
return head;
}
int main()
{
ListNode *L1 = NULL, *L2 = NULL, *mergeHead = NULL;
L1 = InitializeLinkList(L1);
L2 = InitializeLinkList(L2);
for(int i = 2; i < 10; i += 2)
{
CreateLinkList(L1, i);
}
for(int j = 1; j < 10; j += 2)
{
CreateLinkList(L2, j);
}
cout << "鏈表1:";
PrintLinkList(L1);
cout << "鏈表2:";
PrintLinkList(L2);
mergeHead = MergeTwoLinkList(L1->next, L2->next); //是有帶有頭結點的單鏈表
cout << "合併以後的鏈表:";
ListNode *s = mergeHead;
while(s != NULL)
{
cout << s->data << " ";
s = s->next;
}
cout << endl;
system("pause"); return 0;}