小杨想在上题所述的双向链表中加入一首新歌曲。为了能快速找到该歌曲,他将其作为链表的第一首歌曲,则下面横线上应填入的代码为( )。
void insert(dl_node *head, string my_song) {
p = new dl_node;
p->song = my_song;
p->prev = nullptr;
p->next = head;
if (head != nullptr) {
________________________ // 在此处填入代码
}
head = p;
}根据上下文和C++语法规则确定空缺处应填的内容,关注函数调用参数、表达式和返回值类型。
填空时注意语法完整性:分号、括号匹配、函数参数类型和个数、返回值类型。
【考点】指针操作|双向链表|条件判断
插入双链表头结点时,新结点的 next 已指向原头结点,但原头结点作为新第二结点后,其 prev 必须反向指向新头结点,否则双链表断裂。因为新头结点 prev 已在前面赋为 nullptr,所以只需在 head 非空时修改 head->prev = p;若原链表为单结点,head 非空,需处理;若原链表为空,head 为 nullptr,无需修改任何指针。
A 错:head->next 是原链表第二个结点,它的 prev 指向的是原头结点,不是新头结点,改它毫无意义。 B 错:head->next = p 会让原头结点的 next 反向指回新头,形成环,破坏链表结构。 D 错:if (head != nullptr) 已保证 head 非空,head->prev 是合法成员赋值,不会触发异常。
陷阱在于:看到 head 非空就下意识想改它指向的结点,却忘记要改它自己;同时忽略空链表情形导致条件判断多余。
反命题视角:若把插入位置改成末尾,则需判断 tail 并修改 tail->next = p 且 p->prev = tail;若改成在任意位置,则需先找到前驱 prevNode,再执行 prevNode->next = p 且 p->next->prev = p。刷到头插题时先问:"新结点与旧头结点的双向指针谁该变?"