在不带哨兵结点的双向链表中,结点 p 既不是头结点也不是尾结点。删除 p 的正确代码是( )。
struct Node {
int value;
Node *prev;
Node *next;
};A.
p->prev = p->next;
p->next = p->prev;
delete p;B.
p->prev->next = p;
p->next->prev = p;
delete p;C.
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;D.
p->next = p->prev;
p->prev->next = nullptr;
delete p;删除中间结点核心是"先改邻居,再删自己"。看到题先定位 p 的左右邻居 p->prev 和 p->next,然后让左邻居的 next 跳过 p 指向右邻居,右邻居的 prev 跳过 p 指向左邻居,最后 delete p。关键是顺序:必须先完成两个邻居的指针重连,再释放 p,否则 p 被删后邻居指针就悬空了。
A 错在直接改 p 自己的 prev/next,相当于把 p 的指针互指,链表结构没变;B 错在让邻居指向 p,形成环;D 错在只改 p->next 和 p->prev->next,没改 p->next->prev,双向性被破坏。最阴险的是 A 和 B 都保留了 p 的引用,看似"还在链表里",实则逻辑已乱。
删除中间结点核心是"先改邻居,再删自己"。看到题先定位 p 的左右邻居 p->prev 和 p->next,然后让左邻居的 next 跳过 p 指向右邻居,右邻居的 prev 跳过 p 指向左邻居,最后 delete p。关键是顺序:必须先完成两个邻居的指针重连,再释放 p,否则 p 被删后邻居指针就悬空了。
A 错在直接改 p 自己的 prev/next,相当于把 p 的指针互指,链表结构没变;B 错在让邻居指向 p,形成环;D 错在只改 p->next 和 p->prev->next,没改 p->next->prev,双向性被破坏。最阴险的是 A 和 B 都保留了 p 的引用,看似"还在链表里",实则逻辑已乱。
本题考查《GESP 考试大纲》五级"链表操作"模块的指针重连逻辑。命题人卡住的是考生对双向链表"邻居重连顺序"的直觉——绝大多数人只记得单向链表删结点要改 next,却忽略双向链表必须同时改两个方向,且顺序不能错。