typedef struct Node {
int value;
struct Node *next;
struct Node *prev;
} Node;
// 假設 head 為頭節點指針,且鏈表非空
void delete_value(Node **head, int target) {
Node *cur = *head;
while (cur) {
if (cur->value == target) {
// 1. 斷開鏈接
if (cur->prev) cur->prev->next = cur->next;
else *head = cur->next; // 刪除頭節點
if (cur->next) cur->next->prev = cur->prev;
// 2. 釋放內存
free(cur);
return; // 假設值唯一,刪一個即返回
}
cur = cur->next;
}
}
void insert_between(Node *head, int after_val, int before_val, int new_val) {
Node *cur = head;
while (cur && cur->next) {
if (cur->value == after_val && cur->next->value == before_val) {
Node *new_node = malloc(sizeof(Node));
if (!new_node) return; // 分配失敗
new_node->value = new_val;
// 1. 新節點鏈接後繼
new_node->next = cur->next;
new_node->prev = cur;
// 2. 後繼節點回鏈
cur->next->prev = new_node;
// 3. 前驅節點前鏈
cur->next = new_node;
return;
}
cur = cur->next;
}
// 未找到相鄰對,可選:釋放 new_node 或報錯
}
int main() {
// 假設已建立鏈表:... 66 <-> 91 <-> 23 ...
Node *head = build_list(); // 省略構建代碼
delete_value(&head, 91); // 刪除 91
insert_between(head, 66, 23, 68); // 66 和 23 間插 68
// 遍歷驗證
for (Node *p = head; p; p = p->next)
printf("%d ", p->value);
// 釋放整表
while (head) {
Node *tmp = head;
head = head->next;
free(tmp);
}
return 0;
}
| 操作 | 核心步驟 | 邊界情況 |
|---|---|---|
| 刪除 | 前驅->next=後繼;後繼->prev=前驅;free | 刪頭/尾/唯一節點、目標不存在 |
| 插入 | 新節點雙向鏈接;前驅/後繼回鏈 | 插頭/尾、相鄰對不存在、malloc失敗 |
插入前: [66] <-> [23]
↓ ↓
prev=66 prev=23
next=23 next=66
插入後: [66] <-> [68] <-> [23]
↓ ↓ ↓
prev=66 prev=66 prev=68
next=68 next=23 next=68
引入虛擬頭尾節點 head->prev = tail; tail->next = head,形成循環雙向鏈表,刪除/插入無需判斷頭尾,代碼更簡潔健壯,Linux 內核 list_head 即採用此設計。