next 設為 NULL。next 指向被刪節點的後繼。核心難點在於找到被刪節點的前驅,需遍歷鏈表。
#include <stdlib.h>
#include <stdio.h>
struct Node { int num; struct Node *next; };
typedef struct Node *Link;
/* 列印 */
void printList(Link head) {
while (head) { printf("[%d]", head->num); head = head->next; }
putchar('\n');
}
/* 建立鏈表(無虛擬表頭版本) */
Link createList(int *arr, int len) {
if (len == 0) return NULL;
Link head = (Link)malloc(sizeof(struct Node));
if (!head) return NULL;
head->num = arr[0]; head->next = NULL;
Link tail = head;
for (int i = 1; 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;
}
/* 查找節點(返回節點指標) */
Link findNode(Link head, int num) {
while (head) {
if (head->num == num) return head;
head = head->next;
}
return NULL;
}
/* 刪除指定節點 */
Link deleteNode(Link head, Link target) {
if (target == head) { // 情況 1:刪除首節點
Link newHead = head->next;
free(head);
return newHead;
}
Link prev = head;
while (prev->next != target) // 找前驅
prev = prev->next;
if (target->next == NULL) // 情況 2:刪除尾節點
prev->next = NULL;
else // 情況 3:刪除中間節點
prev->next = target->next;
free(target);
return head;
}
/* 主程式互動測試 */
int main() {
int data[6] = {1,2,3,4,5,6};
Link head = createList(data, 6);
if (!head) { puts("記憶體配置失敗"); return 1; }
printf("原始鏈表:"); printList(head);
while (1) {
int num;
printf("請輸入要刪除的編號 (-1 結束):");
if (scanf("%d", &num) != 1 || num == -1) break;
Link target = findNode(head, num);
if (!target) { puts("未找到"); continue; }
head = deleteNode(head, target);
printf("刪除後:"); printList(head);
}
return 0;
}
prev,再統一處理 prev->next 重連。head 指標並釋放原首節點。free(target) 必須在重連指標之後,避免野指標。malloc 返回值。next 設為 NULL,導致殘留懸空指標。free 再訪問 target->next 取後繼,屬未定義行為。