首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言雙向鏈表刪除操作:帶頭尾哨兵節點的統一實現

     編輯:關於C

哨兵節點消除邊界特判

有了虛擬頭尾節點,刪除任意位置/值節點只需統一的指針重連:


/* 刪除第 pos 個有效節點 (1-based) */
bool List_ErasePos(DList *L, int pos) {
    Node *p = L->head->next;
    for (int i = 1; p != L->tail; p = p->next, ++i) {
        if (i == pos) {
            p->prior->next = p->next;
            p->next->prior = p->prior;
            free(p);
            return true;
        }
    }
    return false;
}

/* 刪除第一個值為 val 的節點 */
bool List_EraseVal(DList *L, int val) {
    for (Node *p = L->head->next; p != L->tail; p = p->next) {
        if (p->element == val) {
            p->prior->next = p->next;
            p->next->prior = p->prior;
            free(p);
            return true;
        }
    }
    return false;
}

關鍵點解析

  1. 無需判斷 p 是首節點/尾節點/唯一節點:哨兵的 prior/next 永遠有效指向鄰居。
  2. 指針重連順序:先連接鄰居跨過 p,再 free(p),防止野指針。
  3. 返回 bool:調用者可知曉是否真刪除。

對比:無哨兵版本的痛苦


/* 無哨兵刪除首節點 */
if (p == head) {
    head = p->next;
    if (head) head->prior = NULL;
    free(p);
}
/* 無哨兵刪除尾節點 */
if (p->next == NULL) {
    p->prior->next = NULL;
    free(p);
}
/* 無哨兵刪除中間節點 */
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);

三段重複邏輯,易漏邊界,代碼膨脹 3 倍。

測試驗證


int main(void) {
    DList L; List_Init(&L);
    List_PushBack(&L, 10);
    List_PushBack(&L, 20);
    List_PushBack(&L, 30);   // 10 20 30
    List_ErasePos(&L, 2);    // 刪除 20
    List_PrintForward(&L);   // 10 30
    List_EraseVal(&L, 10);   // 刪除 10
    List_PrintForward(&L);   // 30
    List_EraseVal(&L, 30);   // 刪除 30 (唯一節點)
    List_PrintForward(&L);   // 空
    free(L.head); free(L.tail);
    return 0;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved