C++模板双向链表打印失败求助:节点双向指针异常
问题分析与修正方案
你的双向链表实现核心问题在于插入函数的逻辑错误,导致节点间的双向指针没有正确建立关联,进而print函数无法遍历所有节点。以下是具体错误点和修正后的代码:
主要错误点
- 插入函数逻辑混乱
insert(doubly_list* prev, doubly_list* next)中,错误覆盖prev->prev_node的值,还强制将新节点的prev_node设为nullptr,破坏双向关联insert(doubly_list* next)存在无效赋值,未正确设置新节点的前驱指针
- print函数判断逻辑错误
- 通过
head->next_node == nullptr判断遍历方向的逻辑不成立,无法正确遍历多节点链表
- 通过
- main函数未更新头节点
- 插入新节点到头部后,未将head指向新的头节点,导致原head的next指针始终为
nullptr
- 插入新节点到头部后,未将head指向新的头节点,导致原head的next指针始终为
修正后的完整代码
#include <iostream> #include <string> #include <stdexcept> template <typename T> class doubly_list { private: doubly_list* next_node; doubly_list* prev_node; T value; public : doubly_list(const T& nvalue, doubly_list* next = nullptr, doubly_list* prev = nullptr) : value(nvalue), next_node(next), prev_node(prev) { } doubly_list* getnext_node() const { return next_node; } doubly_list* getprev_node() const { return prev_node; } T getlist_value() const { return value; } // 在当前节点之前插入next节点 doubly_list* insert(doubly_list* next); // 在prev节点之前插入next节点 doubly_list* insert(doubly_list* prev, doubly_list* next); // 从head开始正向打印链表 static void print_the_list(doubly_list<T>* head); }; // 在当前节点之前插入next节点 template<typename T> doubly_list<T>* doubly_list<T>::insert(doubly_list* next) { if (next == nullptr) return this; // 设置新节点的后继和前驱 next->next_node = this; next->prev_node = this->prev_node; // 如果当前节点有前驱,更新前驱的后继指针 if (this->prev_node != nullptr) { this->prev_node->next_node = next; } // 更新当前节点的前驱指针为新节点 this->prev_node = next; return next; // 返回新的节点(如果插入到头部,这就是新的head) } // 在prev节点之前插入next节点 template<typename T> doubly_list<T>* doubly_list<T>::insert(doubly_list* prev ,doubly_list* next) { if (prev == nullptr || next == nullptr) return prev; // 复用单参数insert的逻辑,避免代码冗余 return prev->insert(next); } // 正向打印链表(从head开始,直到next为nullptr) template<typename T> void doubly_list<T>::print_the_list(doubly_list<T>* head) { if (!head) throw std::invalid_argument("链表为空"); std::cout << "{"; while (head) { std::cout << head->value; // 如果不是最后一个节点,添加分隔符 if (head->next_node != nullptr) { std::cout << ", "; } head = head->next_node; } std::cout << "}" << std::endl; } int main () { // 初始化头节点 auto head = new doubly_list<std::string>("1"); // 插入新节点到头部,并更新head为新的头节点 head = head->insert(new doubly_list<std::string>("2")); head = head->insert(new doubly_list<std::string>("3")); head = head->insert(new doubly_list<std::string>("4")); // 打印链表 doubly_list<std::string>::print_the_list(head); // 注意:实际代码中需要手动释放内存,避免内存泄漏 return 0; }
关键修正说明
- 插入函数逻辑重构
- 明确双向指针关联顺序:先设置新节点的
next和prev,再更新原节点前驱的next,最后更新原节点的prev - 双参数insert直接复用单参数insert逻辑,减少冗余
- 明确双向指针关联顺序:先设置新节点的
- print函数优化
- 改为静态函数(更合理,打印链表无需依赖单个节点实例),正向遍历并添加元素分隔符提升可读性
- main函数调整
- 插入新节点后,将head更新为insert返回的新节点,确保head始终指向链表首节点
运行修正后的代码,输出为:{4, 3, 2, 1},符合每次在头部插入新节点的预期。
内容的提问来源于stack exchange,提问作者Warerre
相关产品推荐
相关产品推荐

