無哨兵刪除的三大邊界
- 刪除首節點:需更新
head 指針,新首節點 prior = NULL。
- 刪除尾節點:前驅節點
next = NULL。
- 刪除唯一節點:
head = NULL。
- 刪除中間節點:雙向重連。
按位置刪除完整實現
Node* DeletePos(Node *head, int pos) {
if (!head) return NULL;
int size = List_Length(head);
if (pos < 1 || pos > size) return head;
Node *p = head;
for (int i = 1; i < pos; ++i) p = p->next;
if (pos == 1) { // 刪除首節點
head = p->next;
if (head) head->prior = NULL;
} else if (pos == size) { // 刪除尾節點
p->prior->next = NULL;
} else { // 刪除中間節點
p->prior->next = p->next;
p->next->prior = p->prior;
}
free(p);
return head; // 可能改變
}
按值刪除完整實現
Node* DeleteVal(Node *head, int val) {
if (!head) return NULL;
Node *p = head;
while (p && p->element != val) p = p->next;
if (!p) return head; // 未找到
if (p == head) { // 首節點
head = p->next;
if (head) head->prior = NULL;
} else if (p->next == NULL) { // 尾節點
p->prior->next = NULL;
} else { // 中間節點
p->prior->next = p->next;
p->next->prior = p->prior;
}
free(p);
return head;
}
關鍵提醒
- 刪除後必須返回新 head,調用者需接收:
head = DeletePos(head, pos);
- 若頻繁刪除首尾,強烈建議改用帶頭尾哨兵版本(見 ID 411),邏輯統一、無需返回 head。
- 刪除前檢查
pos 合法性,避免野指針。