基于上题代码正确的前提下,填入相应代码完善 append(),用于在双向链表尾部增加新节点,横线上应填写( )。
void append(int data) {
Node* newNode = new Node{data, nullptr, nullptr};
if (is_empty()) {
head = tail = newNode;
} else {
// 横线处
}
++size;
}A.
tail->next = newNode;B.
newNode->prev = tail;
tail = newNode;C.
tail = newNode;
newNode->prev = tail;
tail->next = newNode;D.
tail->next = newNode;
newNode->prev = tail;
tail = newNode;链表分为单向/双向/循环链表,插入删除O(1),但查找O(n)。注意指针操作的顺序,防止断链。
链表操作要特别注意指针修改的顺序。例如在节点前插入时,先新节点→next = 当前→next,再当前→next = 新节点。顺序颠倒会导致断链。
【考点】双向链表指针操作|尾部插入逻辑|链表状态维护
考查 GESP 五级《数据结构与算法》模块“链表操作”中的双向链表尾部插入。命题人用“双向”二字卡住只会单向链表逻辑的考生,专盯漏设 prev 指针和未更新 tail 的惯性错误。
看到双向链表尾部插入,先想“当前尾部是谁”——head/tail 指针。链式结构里,新节点必须同时接上 tail 的 next 和 tail 的 prev。顺序不能乱:先 tail->next=newNode 把新节点挂上,再 newNode->prev=tail 补回前驱,最后 tail=newNode 更新尾指针。否则要么断链,要么指向已释放的旧 tail。
逐个拆错: A 只设了 next,prev 仍为 nullptr,且 tail 未动——双向链表断链。 B 设了 prev 和 tail,但漏了 tail->next = newNode,新节点悬空。 C 先 tail=newNode 再设 prev,导致新节点指向自己,形成自环,整条链表报废。 D 顺序完美:先挂上,再补前驱,再移尾。命题人专坑“先移尾再挂”的惯性思维。
若改成“头部插入”,横线处应改为 head->prev = newNode; newNode->next = head; head = newNode; 若改成“任意位置插入”,需要遍历到前驱节点再执行 D 的逻辑。命题人换考法时,往往只改“插入位置”,核心指针更新逻辑不变。