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

C 語言實現雙向非循環鏈表清空:遞歸釋放與迭代釋放雙方案

     編輯:關於C語言

雙向鏈表銷毀:利用 prior 指針實現單向釋放

清空雙向非循環鏈表時,可利用 prior 指針從頭向後遍歷,逐個釋放前驅節點,最後釋放尾節點。無頭結點版本需處理空表、單節點等邊界。本文提供迭代法與遞歸法兩種實現,並分析優劣。

迭代法 (推薦,O(1) 空間)

Node* ClearDoubleLinkedList(Node *head) {
    if (!head) { printf("原鏈表已為空\n"); return NULL; }
    
    Node *cur = head;
    // 遍歷釋放前驅節點
    while (cur->next) {
        cur = cur->next;        // 移動到下一個
        free(cur->prior);       // 釋放前一個
        cur->prior = NULL;      // 斷開回連 (防野指針)
    }
    // 釋放最後一個節點 (尾節點)
    free(cur);
    
    printf("雙向鏈表清空完成\n");
    return NULL;
}

遞歸法 (教學演示,O(n) 棧空間)

void ClearRecursive(Node *node) {
    if (!node) return;
    ClearRecursive(node->next);
    free(node);
}

// 調用:
ClearRecursive(head);
head = NULL;
// 注意: 長鏈表會棧溢出,生產環境禁用

迭代過程圖解

原鏈表: [10] <-> [20] <-> [30] <-> NULL
          head

步驟 1: cur=head(10), cur->next 存在
cur = cur->next  => cur 指向 20
free(cur->prior) => 釋放 10
cur->prior = NULL => 20->prior = NULL

步驟 2: cur=20, cur->next 存在
cur = cur->next  => cur 指向 30
free(cur->prior) => 釋放 20
cur->prior = NULL => 30->prior = NULL

步驟 3: cur=30, cur->next == NULL (循環結束)
free(cur) => 釋放 30
返回 NULL

關鍵點總結

要點說明
遍歷方向必須從頭向尾 (沿 next),利用 prior 釋放已訪問節點
尾節點處理循環結束時 cur 指向尾節點,需額外 free(cur)
斷開指針cur->prior = NULL 防止釋放後內存被誤訪問 (好習慣)
返回值返回 NULL 表示鏈表已銷毀,調用端應接收: head = Clear(head)
帶頭結點版從 head->next 開始,保留 head 節點,邏輯類似

對比:單向 vs 雙向鏈表清空

方式單向鏈表雙向鏈表
迭代釋放需保存 next: next = cur->next; free(cur); cur = next;利用 prior: cur = cur->next; free(cur->prior);
代碼簡潔度略繁更直觀
遞歸風險同 (棧溢出)同

測試驗證

int main() {
    Node *list = NULL;
    list = createList(list); // 10 20 30 0
    printList(list);         // 10 20 30
    list = ClearDoubleLinkedList(list);
    printList(list);         // (空)
    list = ClearDoubleLinkedList(list); // 空表調用
    return 0;
}

總結

雙向鏈表清空利用 prior 指針實現了「邊遍歷邊釋放前驅」的優雅模式,代碼比單向鏈表更簡潔。**生產環境必須使用迭代法**,避免遞歸棧溢出。若使用帶頭結點循環雙向鏈表 (Linux list_head),清空可簡化為 while (!list_empty(head)) { list_del(head->next); free(head->next); },進一步體現標準庫接口的威力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved