# C++怎么合并兩個排序的鏈表
## 引言
在數據結構與算法中,合并兩個已排序的鏈表是一個經典問題。該問題不僅考察對鏈表操作的理解,還涉及遞歸和迭代兩種解題思路。本文將詳細介紹在C++中如何高效實現這一操作,包括代碼實現、復雜度分析以及相關應用場景。
---
## 問題描述
給定兩個**非遞減順序排列**的鏈表`list1`和`list2`,要求將它們合并為一個新的**升序鏈表**并返回。新鏈表應通過拼接原鏈表的節點組成。
**示例輸入:**
```cpp
List1: 1 -> 3 -> 5
List2: 2 -> 4 -> 6
示例輸出:
1 -> 2 -> 3 -> 4 -> 5 -> 6
首先,我們需要定義鏈表節點的結構。在C++中,通常如下表示:
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
curr
跟蹤新鏈表的當前節點。ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode dummy(0); // 虛擬頭節點
ListNode* curr = &dummy;
while (list1 && list2) {
if (list1->val <= list2->val) {
curr->next = list1;
list1 = list1->next;
} else {
curr->next = list2;
list2 = list2->next;
}
curr = curr->next;
}
// 處理剩余節點
curr->next = list1 ? list1 : list2;
return dummy.next;
}
list1->val
較小,則將list1->next
與list2
合并的結果接入list1
。ListNode* mergeTwoListsRecursive(ListNode* list1, ListNode* list2) {
if (!list1) return list2;
if (!list2) return list1;
if (list1->val <= list2->val) {
list1->next = mergeTwoListsRecursive(list1->next, list2);
return list1;
} else {
list2->next = mergeTwoListsRecursive(list1, list2->next);
return list2;
}
}
方法 | 優點 | 缺點 |
---|---|---|
迭代法 | 空間效率高(O(1)) | 代碼稍顯冗長 |
遞歸法 | 代碼簡潔,邏輯清晰 | ??臻g開銷大(O(n+m)) |
實際編碼時需考慮以下特殊情況:
1. 一個鏈表為空:直接返回另一個鏈表。
2. 兩個鏈表均為空:返回nullptr
。
3. 鏈表有重復值:題目要求非遞減順序,重復值需保留。
#include <iostream>
using namespace std;
// 打印鏈表
void printList(ListNode* head) {
while (head) {
cout << head->val << " -> ";
head = head->next;
}
cout << "nullptr" << endl;
}
// 測試代碼
int main() {
// 構造鏈表1: 1->3->5
ListNode a(1), b(3), c(5);
a.next = &b; b.next = &c;
// 構造鏈表2: 2->4->6
ListNode d(2), e(4), f(6);
d.next = &e; e.next = &f;
cout << "List1: "; printList(&a);
cout << "List2: "; printList(&d);
// 合并鏈表
ListNode* merged = mergeTwoLists(&a, &d);
cout << "Merged: "; printList(merged);
return 0;
}
輸出結果:
List1: 1 -> 3 -> 5 -> nullptr
List2: 2 -> 4 -> 6 -> nullptr
Merged: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> nullptr
A1: 可以。迭代法通過指針重定向實現原地合并,無需額外節點(虛擬頭節點除外)。
A2: 若鏈表為降序,可先反轉鏈表再合并,或修改比較邏輯為list1->val >= list2->val
。
A3: 當鏈表極長時(如數萬節點),遞歸可能導致棧溢出,此時應使用迭代法。
prev
指針,但核心邏輯相似。本文詳細講解了在C++中合并兩個有序鏈表的兩種方法: - 迭代法:推薦生產環境使用,空間效率高。 - 遞歸法:適合面試或小規模數據,代碼簡潔。
理解這一問題的解決方案,將為處理更復雜的鏈表操作(如環形鏈表檢測、重排序等)奠定堅實基礎。
<list>
實現原理”`
注:實際字數約1800字,可根據需要增減示例或優化細節以達到精確字數要求。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。