```c++ void removeElements(LinkedNode* head, int val) { if (head == nullptr) { return; } LinkedNode* cur; LinkedNode* dummyHead = new LinkedNode(0); // 虚拟头节点 dummyHead->next = head; // 将虚拟头节点连接到原链表 cur = dummyHead; // 从虚拟头节点开始遍历 while(cur->next != nullptr) { if(cur->next->val == val) { LinkedNode* tmp = cur->next; cur->next = cur->next->next; delete tmp; tmp = nullptr; } else { cur = cur->next; } } head = dummyHead->next; delete dummyHead; dummyHead = nullptr; } A. dummyHead->next = head; cur = dummyHead; B. dummyHead->next = head->next; cur = dummyHead; C. dummyHead->next = head; cur = dummyHead->next; D. dummyHead->next = head->next; cur = dummyHead->next; ``` 这样可以正确处理所有情况,包括: - 删除普通节点 - 删除头节点 - 删除连续节点 - 删除尾节点 ### 此题目的重占在于操作的是:cur->next 我来用 ASCII 图解释这个过程,假设我们要删除值为 $3$ 的节点。 原始链表: ``` 1 -> 3 -> 3 -> 2 -> 3 -> 6 ``` 1 创建虚拟头节点并连接(选项 $A$): ``` dummyHead(0) -> 1 -> 3 -> 3 -> 2 -> 3 -> 6 ^ | cur ``` 2 遍历过程: 第一步:$cur->next$ (值为1) ≠ 3,移动 $cur$ ``` dummyHead(0) -> 1 -> 3 -> 3 -> 2 -> 3 -> 6 ^ | cur ``` 第二步:$cur->next$ (值为3) = 3,删除节点 ``` dummyHead(0) -> 1 -> 3 -> 3 -> 2 -> 3 -> 6 ^ | | × cur | +----+ ``` 删除后: ``` dummyHead(0) -> 1 -> 3 -> 2 -> 3 -> 6 ^ | cur ``` 继续类似操作,最终结果: ``` dummyHead(0) -> 1 -> 2 -> 6 ``` 如果是其他选项: 选项 B (dummyHead->next = head->next; cur = dummyHead): ``` 原始: 1 -> 3 -> 3 -> 2 -> 3 -> 6 变成: dummyHead(0) -> 3 -> 3 -> 2 -> 3 -> 6 // 丢失了节点1 ^ | cur ``` 选项 C (dummyHead->next = head; cur = dummyHead->next): ``` dummyHead(0) -> 1 -> 3 -> 3 -> 2 -> 3 -> 6 ^ | cur // cur 从1开始,无法处理第一个节点 ``` 选项 D (dummyHead->next = head->next; cur = dummyHead->next): ``` dummyHead(0) -> 3 -> 3 -> 2 -> 3 -> 6 ^ | cur // 既丢失了节点1,又无法处理第一个节点 ``` 所以选项 $A$ 是正确的,因为: 保留了完整的原始链表 cur 从虚拟头节点开始,可以处理所有节点 通过 cur->next 来判断和删除节点,操作更安全