設計文件:連結串列逆置模組
- 問題描述
本題要求實現一個函式,將給定的單向連結串列逆置,即表頭置為表尾,表尾置為表頭。給定連結串列的節點結構如下:
c
struct ListNode {
int data;
struct ListNode *next;
};
函式介面如下:
c
struct ListNode *reverse(struct ListNode *head);
其中,head 是使用者傳入的連結串列的頭指標。該函式需要將連結串列逆置,並返回逆置後的連結串列頭指標。
- 函式功能
函式的核心功能是將單向連結串列逆置。具體而言:
輸入:單向連結串列的頭節點 head。
輸出:逆置後的單向連結串列的頭節點。
3. 演算法設計
連結串列逆置的基本思路是透過修改節點的 next 指標來反轉連結串列的方向。
初始化一個 prev 指標,表示已經處理的部分,初始化為 NULL。
遍歷連結串列,每次更新當前節點的 next 指標,使其指向前一個節點。
依次處理連結串列中的每個節點,直到遍歷完連結串列。
具體步驟:
初始化 prev 為 NULL,curr 為連結串列的頭節點。
遍歷連結串列,對於每個節點:
儲存當前節點的下一個節點 next。
將當前節點的 next 指標指向 prev,即反轉指向關係。
移動 prev 和 curr 指標向前。
最終,prev 會指向連結串列的最後一個節點,即新的頭節點。
4. 模組圖
由於目前不支援插入圖片,因此請參考以下文字描述手繪模組圖:
+------------------------+
| 輸入:連結串列頭節點 head |
+------------------------+
|
V
+------------------------+
| 初始化指標 prev=NULL |
+------------------------+
|
V
+------------------------+
| 遍歷連結串列,更新指標 next |
+------------------------+
|
V
+------------------------+
| 返回反轉後的頭節點 |
+------------------------+
5. 程式碼實現
c
include <stdio.h>
include <stdlib.h>
struct ListNode {
int data;
struct ListNode *next;
};
// 反轉連結串列函式
struct ListNode *reverse(struct ListNode *head) {
struct ListNode *prev = NULL, *curr = head, *next = NULL;
// 遍歷連結串列
while (curr != NULL) {
next = curr->next; // 儲存當前節點的下一個節點
curr->next = prev; // 反轉當前節點的next指標
prev = curr; // prev向後移動
curr = next; // curr向後移動
}
return prev; // 返回新的頭節點
}
// 輔助函式:建立連結串列
struct ListNode *createlist() {
int value;
struct ListNode *head = NULL, *tail = NULL;
// 輸入連結串列資料
while (scanf("%d", &value) && value != -1) {
struct ListNode *new_node = (struct ListNode *)malloc(sizeof(struct ListNode));
new_node->data = value;
new_node->next = NULL;
if (head == NULL) {
head = new_node;
tail = new_node;
} else {
tail->next = new_node;
tail = new_node;
}
}
return head;
}
// 列印連結串列
void printlist(struct ListNode *head) {
struct ListNode *p = head;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main() {
struct ListNode *head;
// 建立連結串列並逆置
head = createlist();
head = reverse(head);
// 列印逆置後的連結串列
printlist(head);
return 0;
}
6. 程式碼解釋
reverse 函式:
prev 指標用來記錄已反轉部分的尾節點。
curr 指標用來遍歷連結串列中的節點。
next 用來儲存當前節點的下一個節點,以避免斷鏈。
反轉過程中,每次將當前節點的 next 指標指向 prev,然後更新 prev 和 curr。
最終返回的 prev 是反轉後的連結串列頭。
createlist 函式:
動態建立連結串列,直到輸入 -1 時停止。
每個新節點透過 malloc 建立,並將其連結到連結串列的尾部。
printlist 函式:
遍歷連結串列並列印每個節點的資料。
7. 測試樣例
輸入樣例:
1 2 3 4 5 6 -1
輸出樣例:
6 5 4 3 2 1
8. 時間與空間複雜度
時間複雜度:
由於我們只需要遍歷連結串列一次,時間複雜度為 O(n),其中 n 是連結串列中的節點數。
空間複雜度:
我們只使用了常數空間儲存指標,因此空間複雜度為 O(1)。
- 總結
該函式實現了連結串列的反轉,並透過指標操作實現了高效的反轉演算法。函式遵循連結串列的基本操作原則,時間和空間複雜度均為最優解。