XOR链表通过存储prev^next异或值节省一个指针空间,但需双指针遍历、无法随机访问、地址移动即失效,仅适用于极低内存嵌入式场景。

什么是 XOR 链表,它真能省空间?
能省,但只省指针域本身——单链表每个节点存 1 个 next 指针(8 字节),XOR 链表改存 nxor = prev ^ next(还是 8 字节),节点少存 1 个指针字段。对百万级节点的链表,确实省下几 MB 内存;但代价是无法随机访问、不能双向遍历、所有操作都依赖已知相邻节点。
它不是“更高效的数据结构”,而是“用计算换存储”的权衡。现代 CPU 缓存友好性远比节省几个字节重要,所以除非你在嵌入式环境里抠每字节内存,否则基本不用。
C++ 中怎么实现 XOR 链表的核心操作?
关键在用 uintptr_t 存地址、用异或模拟双向指针跳转。不能直接对指针做 ^,必须先转整型;也不能用 reinterpret_cast 转回指针后直接解引用——需确保地址合法且对齐。
-
nxor字段类型必须是uintptr_t,不是void*或intptr_t - 前驱/后继地址恢复公式:已知
curr、prev,则next = reinterpret_cast<node>(static_cast<uintptr_t>(curr->nxor) ^ reinterpret_cast<uintptr_t>(prev))</uintptr_t></uintptr_t></node> - 插入/删除时,必须从已知节点出发更新邻接节点的
nxor,不能孤立修改 - 头节点的
nxor实际存的是nullptr ^ next,即等于next地址;尾节点同理
为什么遍历 XOR 链表必须带两个指针?
因为 nxor 是异或结果,单靠一个节点无法解出 next 或 prev —— 异或运算不可逆,除非你有其中一个原始操作数。所以任何遍历都至少需要 curr 和 prev(或 next)两个变量。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
常见错误现象:Segmentation fault 或野指针访问,往往是因为初始化时把 prev 设成了未初始化的栈变量,或者遍历到头/尾时没正确设 prev = nullptr。
- 正向遍历起始:设
prev = nullptr,curr = head - 反向遍历起始:设
next = nullptr,curr = tail(但你得先找到 tail,这本身就要遍历一遍) - 不能像普通链表那样写
for (auto p = head; p; p = p->next)—— 这里没有p->next
实际项目里该不该用?
绝大多数 C++ 项目不该用。STL 的 std::list 是双向链表,每个节点 3 个指针(prev/next/data),XOR 版最多省 1 个指针,但失去迭代器稳定性、不支持 std::reverse_iterator、无法用 std::find_if 直接遍历、调试时几乎没法看 nxor 值含义。
真正适合的场景极少:比如裸机固件中维护一个固定长度的硬件描述符链表,且编译器不支持标准库、RAM 小于 64KB。
最容易被忽略的一点:XOR 链表的节点地址一旦被移动(比如 vector 重分配、内存整理),nxor 值立刻失效——它存的是绝对地址,不是偏移。这点比普通指针更脆弱。


















