在《C語言實現單鏈表節點的刪除(不帶頭結點)》中,我們已探討無頭結點鏈表的節點刪除。本文將重點講解帶頭結點單鏈表中兩種常見的刪除操作:按指定位置刪除與按節點值刪除。帶頭結點的設計統一了頭節點與普通節點的操作邏輯,使代碼更簡潔健壯。
無論哪種刪除方式,核心都是維護兩個指針:
pMovePre:指向當前檢查節點的前驅節點(初始指向頭結點)。pMove:指向當前待檢查節點(初始指向第一個數據節點)。遍歷過程中,若滿足刪除條件,只需將 pMovePre->next 指向 pMove->next,然後釋放 pMove 內存,即可完成刪除。這得益於頭結點的存在,無需單獨處理刪除第一個數據節點的特殊情況。
/**
* 刪除指定位置 pos 的節點(位置從 1 開始計數)
* @param pNode 帶頭結點的鏈表頭指針
* @param pos 要刪除的節點位置
* @return 鏈表頭指針
*/
Node *DeletePosNode(Node *pNode, int pos) {
int i = 1;
Node *pMovePre = pNode; // 前驅指針從頭結點開始
Node *pMove = pNode->next; // 當前指針從第一個數據節點開始
while (pMove != NULL) {
if (i == pos) {
// 找到目標位置,執行刪除
pMovePre->next = pMove->next;
free(pMove);
pMove = NULL;
printf("%s函數執行,在pos=%d位置刪除節點成功\n", __FUNCTION__, pos);
return pNode;
}
i++;
pMovePre = pMovePre->next;
pMove = pMove->next;
}
printf("%s函數執行,在pos=%d位置刪除節點失敗(位置越界)\n", __FUNCTION__, pos);
return pNode;
}
/**
* 刪除值為 x 的第一個節點
* @param pNode 帶頭結點的鏈表頭指針
* @param x 要刪除的節點值
* @return 鏈表頭指針
*/
Node *DeleteValueNode(Node *pNode, int x) {
Node *pMovePre = pNode;
Node *pMove = pNode->next;
while (pMove != NULL) {
if (pMove->element == x) {
// 找到目標值,執行刪除
pMovePre->next = pMove->next;
free(pMove);
pMove = NULL;
printf("%s函數執行,刪除value=%d節點成功\n", __FUNCTION__, x);
return pNode;
}
pMovePre = pMovePre->next;
pMove = pMove->next;
}
printf("%s函數執行,刪除value=%d節點失敗(值不存在)\n", __FUNCTION__, x);
return pNode;
}
| 對比項 | 按位置刪除 | 按值刪除 |
|---|---|---|
| 判斷條件 | 計數器 i == pos | 數據域 pMove->element == x |
| 適用場景 | 已知具體位置(如刪除第 3 個) | 已知數據值(如刪除值為 100 的節點) |
| 時間複雜度 | O(n) | O(n) |
| 邊界處理 | pos < 1 或超過長度視為失敗 | 值不存在視為失敗 |
帶頭結點的單鏈表刪除操作,通過統一的雙指針遍歷邏輯,優雅地解決了頭節點刪除的特殊情況。按位置與按值刪除的核心代碼高度相似,只需修改判斷條件即可。實際開發中,建議封裝為通用的刪除函數,提高代碼復用性與可維護性。