引入一個不存儲有效資料的虛擬表頭節點,可統一「空鏈表」與「非空鏈表」的操作邏輯:插入、刪除、查找均無需特別判斷是否操作第一個節點,代碼更簡潔、錯誤更少。
#include <stdlib.h>
#include <stdio.h>
struct Node {
int num;
struct Node *next;
};
typedef struct Node *Link;
Link createList(int *arr, int len) {
Link head = (Link)malloc(sizeof(struct Node));
if (!head) { fprintf(stderr, "記憶體配置失敗\n"); return NULL; }
head->next = NULL;
Link tail = head;
for (int i = 0; i < len; ++i) {
Link node = (Link)malloc(sizeof(struct Node));
if (!node) { /* 需釋放已分配節點,此處略 */ return NULL; }
node->num = arr[i];
node->next = NULL;
tail->next = node;
tail = node;
}
return head; // 返回虛擬表頭
}
void printList(Link head) {
Link p = head->next; // 跳過虛擬表頭
while (p) {
printf("%d ", p->num);
p = p->next;
}
putchar('\n');
}
Link findNode(Link head, int value) {
Link p = head->next;
while (p) {
if (p->num == value) return p;
p = p->next;
}
return NULL;
}
Link insertNode(Link head, int afterValue, int newValue) {
Link newNode = (Link)malloc(sizeof(struct Node));
if (!newNode) return NULL;
newNode->num = newValue;
newNode->next = NULL;
Link target = findNode(head, afterValue);
if (!target) { // 未找到:插在第一個數據節點之前
newNode->next = head->next;
head->next = newNode;
} else { // 找到:插在目標節點之後
newNode->next = target->next;
target->next = newNode;
}
return head;
}
int main() {
int data[6] = {1,2,3,4,5,6};
Link head = createList(data, 6);
if (!head) return 1;
printf("原始鏈表:");
printList(head);
head = insertNode(head, 6, 23); // 在值為 6 的節點後插入 23
printf("插入後:");
printList(head);
// 記憶體釋放略
return 0;
}
malloc 必須檢查返回值;生產代碼應補全錯誤路徑下的記憶體釋放。head->next 起始,跳過虛擬節點。