鏈表節點刪除是數據結構基礎操作之一。本文詳細講解兩種常見刪除場景:按位置刪除與按值刪除,並給出完整的 C 語言實現代碼,包含邊界條件處理、內存釋放及錯誤提示。
pos-1 個節點(前驅節點),修改其 next 指向被刪節點的下一個節點,釋放被刪節點。pMovePre(前驅)和 pMove(當前)同步遍歷,找到值匹配的節點,修改前驅 next 跳過當前節點,釋放當前節點。// 假設節點結構定義如下
typedef struct Node {
int element;
struct Node *next;
} Node;
// 輔助函數:獲取鏈表長度
int sizeList(Node *pNode) {
int len = 0;
while (pNode) { len++; pNode = pNode->next; }
return len;
}
// 刪除 pos 位置的節點(位置從 1 開始)
Node *deletePosElement(Node *pNode, int pos) {
if (pos <= 0 || pos > sizeList(pNode)) {
printf("%s函數執行,輸入pos值非法,刪除節點失敗\n", __FUNCTION__);
return NULL;
}
Node *pHead = pNode;
Node *pMove = pNode;
int i = 1;
// 刪除頭結點
if (pos == 1) {
pMove = pMove->next;
pNode = pMove;
free(pHead);
printf("%s函數執行,刪除pos=1位置元素成功\n", __FUNCTION__);
return pNode;
}
// 找到前驅節點
while (pMove != NULL) {
if (i == pos - 1) break;
i++;
pMove = pMove->next;
}
// 釋放目標節點並重鏈
Node *toFree = pMove->next;
pMove->next = toFree->next;
free(toFree);
printf("%s函數執行,刪除pos=%d位置元素成功\n", __FUNCTION__, pos);
return pNode;
}
// 刪除值為 x 的第一個節點
Node *deleteXElement(Node *pNode, int x) {
if (pNode == NULL) {
printf("%s函數執行,鏈表為空,刪除x=%d失敗\n", __FUNCTION__, x);
return NULL;
}
Node *pMovePre = pNode;
Node *pMove = pMovePre->next;
// 頭結點匹配
if (pMovePre->element == x) {
pNode = pMove;
free(pMovePre);
return pNode;
}
// 遍歷查找
while (pMove != NULL) {
if (pMove->element == x) {
pMovePre->next = pMove->next;
free(pMove);
break;
}
pMove = pMove->next;
pMovePre = pMovePre->next;
}
if (pMove == NULL) {
printf("%s函數執行,不存在x=%d,刪除數據失敗\n", __FUNCTION__, x);
return pNode;
}
printf("%s函數執行,刪除x=%d成功\n", __FUNCTION__, x);
return pNode;
}
free 被刪節點,避免洩漏。next 指向被刪節點的 next。若需刪除所有值為 x 的節點,可在循環中不 break,繼續遍歷;若鏈表帶虛擬頭結點,可統一邏輯無需特判頭結點。掌握雙指針遍歷模式(前驅+當前)是鏈表修改操作的通用技巧。