双向链表逆序是就地交换每个节点的next和prev指针,并最终交换头尾指针;需遍历所有节点执行指针交换,空链表直接返回,单节点仍需交换头尾;推荐从head出发用while遍历,避免断链。

双向链表逆序的核心是交换每个节点的 next 和 prev 指针
不是“把节点从尾到头重新链接”,而是就地翻转每一对指针指向。原头变尾、原尾变头,但所有节点内存地址不变。关键在于:必须同时更新两个指针,且不能提前丢失任一方向的引用。
常见错误是只改 next 忘了 prev,或在交换过程中用临时变量保存错方向(比如只存 next 却没存 prev,导致遍历时断链)。
- 必须遍历全部节点,对每个
node执行:swap(node->next, node->prev) - 遍历结束后,还要交换头指针和尾指针本身(
head↔tail),否则外部引用仍指向旧头 - 空链表或单节点链表可直接返回,无需操作
std::swap 能安全完成指针交换,但手动写交换逻辑更利于理解边界
用 std::swap 简洁可靠,但初学时建议手写三步交换,看清指针暂存时机:
Node* temp = node->next; node->next = node->prev; node->prev = temp;
注意:不能写成 node->next = node->prev; node->prev = node->next; —— 第二步的 node->next 已被覆盖,node->prev 会得到错误值。
- 如果使用
std::swap,确保包含(C++11 及以后) - 手写交换时,临时变量类型必须与指针一致(如
Node*),不能用auto推导失败(尤其当next/prev是const Node*时) - 迭代器或范围 for 不适用于此场景——双向链表无随机访问,必须用 while 或传统 for 遍历
遍历方向不影响结果,但用 while (curr != nullptr) 最稳妥
可以从原 head 开始向后遍历,也可以从 tail 开始向前遍历。两者效果完全等价,因为每个节点的指针翻转是独立的。但推荐从 head 出发,逻辑更符合直觉,也避免误判 tail 是否为空。
- 循环条件必须是
curr != nullptr,不能是curr->next != nullptr—— 否则最后一个节点被跳过 - 不需要额外判断是否到达末尾;只要节点非空,就翻转它的两个指针
- 翻转完成后,原
head的next指向 null,prev指向原第二个节点——它已变成新链表的第二个节点,符合预期
容易被忽略的是头尾指针本身的交换和空链表处理
很多实现翻转了全部节点指针,却忘了最后两行:std::swap(head, tail)。这会导致调用方仍用 head 遍历,结果只输出一个节点(原尾节点),因为它的 next 是 nullptr。
- 空链表(
head == nullptr)必须提前 return,否则解引用崩溃 - 单节点时,
next和prev都为nullptr,交换无影响,但仍需交换head和tail(虽然值相同) - 若链表封装在类中,该操作应作为成员函数,且需保证
head和tail是可修改的成员变量,而非 getter 返回的副本
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











