#define MAXSIZE 100
typedef struct {
int data[MAXSIZE];
int length;
} SqlList;
/**
* 合併兩個順序表:L2 追加到 L1 尾部
* @param L1 目標表 (引用,會被修改)
* @param L2 來源表 (傳值/引用均可,不修改)
* @return 0 成功, -1 空間不足
*/
int MergeList(SqlList &L1, const SqlList &L2) {
// 1. 檢查空間是否足夠
if (L1.length + L2.length > MAXSIZE) {
return -1; // 溢出
}
// 2. 複製 L2 元素到 L1 尾部
for (int i = 0; i < L2.length; ++i) {
L1.data[L1.length + i] = L2.data[i];
}
// 3. 更新 L1 長度
L1.length += L2.length;
return 0;
}
struct Node {
int data;
Node* next;
Node(int val) : data(val), next(nullptr) {}
};
typedef Node* LinkList; // 頭指標
/**
* 合併兩個單向鏈表:L2 接在 L1 尾部
* @param L1 目標表頭指標 (引用,可能修改頭指標)
* @param L2 來源表頭指標
* @return void
*/
void MergeList(LinkList &L1, LinkList L2) {
if (L2 == nullptr) return; // L2 空,無操作
if (L1 == nullptr) { // L1 空,直接指向 L2
L1 = L2;
return;
}
// 找到 L1 尾節點
Node* tail = L1;
while (tail->next != nullptr) {
tail = tail->next;
}
// 尾節點指向 L2 頭
tail->next = L2;
// L2 現在屬於 L1,調用者不應再使用 L2
}
#include
using namespace std;
#define MAXSIZE 100
typedef struct {
int data[MAXSIZE];
int length;
} SqlList;
int MergeList(SqlList &L1, const SqlList &L2) {
if (L1.length + L2.length > MAXSIZE) return -1;
for (int i = 0; i < L2.length; ++i)
L1.data[L1.length + i] = L2.data[i];
L1.length += L2.length;
return 0;
}
void PrintList(const SqlList &L) {
for (int i = 0; i < L.length; ++i) cout << L.data[i] << " ";
cout << endl;
}
int main() {
SqlList L1 = {{1,2,3,4,5}, 5};
SqlList L2 = {{6,7,8,9,10}, 5};
cout << "合併前 L1: "; PrintList(L1);
cout << "合併前 L2: "; PrintList(L2);
if (MergeList(L1, L2) == 0) {
cout << "合併後 L1: "; PrintList(L1);
} else {
cout << "合併失敗:空間不足\n";
}
return 0;
}
合併前 L1: 1 2 3 4 5
合併前 L2: 6 7 8 9 10
合併後 L1: 1 2 3 4 5 6 7 8 9 10
| 場景 | 核心邏輯 | 複雜度 | 注意事項 |
|---|---|---|---|
| 順序表 (陣列) | 檢查容量 → `memcpy`/迴圈複製 → 更新長度 | O(L2.length) | 固定容量 `MAXSIZE`,需檢查溢出 |
| 鏈表 | 找尾節點 → `tail->next = L2_head` | O(L1.length) 找尾 | 無容量限制,L2 併入後不可再獨立使用 |
| 已排序合併 | 雙指針歸併 (如合併排序 merge 步驟) | O(n+m) | 題目明確「不排序,直接合併」 |
// vector 版 (動態陣列,自動擴容)
void mergeVector(vector &v1, const vector &v2) {
v1.insert(v1.end(), v2.begin(), v2.end());
}
// list 版 (雙向鏈表,拼接 O(1))
void mergeList(list &l1, list &l2) {
l1.splice(l1.end(), l2); // l2 變空,元素移動到 l1
}
線性表合併核心:**順序表檢查容量後複製、鏈表找尾接頭**。題目要求「不排序、直接合併」,單純尾部拼接即可。教學環境常用固定陣列 `SqlList`,實務建議用 `std::vector` 或 `std::list` 享受自動記憶體管理與豐富演算法支援。