You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++模板双向链表打印失败求助:节点双向指针异常

问题分析与修正方案

你的双向链表实现核心问题在于插入函数的逻辑错误,导致节点间的双向指针没有正确建立关联,进而print函数无法遍历所有节点。以下是具体错误点和修正后的代码:

主要错误点

  1. 插入函数逻辑混乱
    • insert(doubly_list* prev, doubly_list* next)中,错误覆盖prev->prev_node的值,还强制将新节点的prev_node设为nullptr,破坏双向关联
    • insert(doubly_list* next)存在无效赋值,未正确设置新节点的前驱指针
  2. print函数判断逻辑错误
    • 通过head->next_node == nullptr判断遍历方向的逻辑不成立,无法正确遍历多节点链表
  3. main函数未更新头节点
    • 插入新节点到头部后,未将head指向新的头节点,导致原head的next指针始终为nullptr

修正后的完整代码

#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;
}

关键修正说明

  1. 插入函数逻辑重构
    • 明确双向指针关联顺序:先设置新节点的next和prev,再更新原节点前驱的next,最后更新原节点的prev
    • 双参数insert直接复用单参数insert逻辑,减少冗余
  2. print函数优化
    • 改为静态函数(更合理,打印链表无需依赖单个节点实例),正向遍历并添加元素分隔符提升可读性
  3. main函数调整
    • 插入新节点后,将head更新为insert返回的新节点,确保head始终指向链表首节点

运行修正后的代码,输出为:{4, 3, 2, 1},符合每次在头部插入新节点的预期。

内容的提问来源于stack exchange,提问作者Warerre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 17:23:22