C++ 在末尾插入双链接列表节点

C++ 在末尾插入双链接列表节点,c++,C++,我正在尝试创建一个函数,用于在双链接列表的末尾添加。我无法精确指出为什么它没有打印出任何内容 当我构建程序时,没有出现错误 我确信 1.新建节点首先检查头部是否有任何值 在上一个当前指针之后创建 我将前一个节点连接到新节点,新节点指向前一个节点,而新节点指向nullptr作为下一个节点 #包括“pch.h” #包括 使用名称空间std; 班级名单; 类节点{ 公众: int数据; 节点*下一步; 节点*prev; 好友类列表; }; 类列表{//双列表 节点*头; 节点*尾部; 公众: list

我正在尝试创建一个函数,用于在双链接列表的末尾添加。我无法精确指出为什么它没有打印出任何内容

当我构建程序时,没有出现错误

我确信 1.新建节点首先检查头部是否有任何值

  • 在上一个当前指针之后创建

  • 我将前一个节点连接到新节点,新节点指向前一个节点,而新节点指向nullptr作为下一个节点

  • #包括“pch.h”
    #包括
    使用名称空间std;
    班级名单;
    类节点{
    公众:
    int数据;
    节点*下一步;
    节点*prev;
    好友类列表;
    };
    类列表{//双列表
    节点*头;
    节点*尾部;
    公众:
    list(){head=nullptr;tail=nullptr;head->next=tail;tail->prev=head;}
    节点*回推(int newdata){
    节点*curr=新节点;
    当前->数据=新数据;
    curr->next=nullptr;
    if(head==nullptr){
    水头=电流;
    回流头;
    }
    节点*precurr=头部;
    while(预curr->next!=nullptr){
    预curr=预curr->next;
    }
    预curr->next=当前;
    当前->当前=预当前;
    回流头;
    }
    作废打印(){
    while(head->next!=nullptr){
    
    cout data您已经做了很多正确的事情,但是您对构造函数以及对
    ->prev
    tail
    指针的使用感到困惑

    如注释中所述,您的构造函数的直接问题是您将
    head
    tail
    设置为
    nullptr
    ,然后立即取消
    head
    tail
    的引用,试图进行
    head
    tail
    自引用(仅在循环链接列表中需要)

    通过将
    head
    tail
    设置为
    nullptr
    ,您没有一个指向有效
    节点的指针,因此无法取消引用。您尝试设置
    head->next=tail;tail->prev=head;
    时立即失败,导致SegFault

    对于普通非循环列表,只需在构造函数中省略设置
    head->next
    tail->prev
    ,例如

        list() { head = nullptr; tail = nullptr; }
    
    如果您想使列表成为循环列表,那么您将在以下位置进行
    head
    tail
    自引用:

        node *pushback (int newdata) {
            ...
            if (head == nullptr)     /* for circular-list 1st node initialization */
                head = tail = head->prev = head->next = tail->prev = tail->next = curr;
    
    注意:a
    tail
    指针是可选的,循环列表为
    head->prev
    始终指向列表中的最后一个节点)

    由于您的问题属于双链接列表而不是循环列表,因此您只需将
    设置为等于新节点
    curr
    ,以添加第一个节点,例如

        node *pushback (int newdata) {
            node *curr = new node;
            curr->data = newdata;
            curr->next = curr->prev = nullptr;
    
            if (head == nullptr)
                head = tail = curr;
    
    对于所有其他节点,不需要迭代(这就是
    tail
    指针的作用),只需将
    curr->prev
    设置为
    tail
    tail->next
    设置为
    curr
    ,然后通过设置
    tail=curr;
    ,更新指向新结束节点的
    tail
    指针

            else {
                curr->prev = tail;
                tail->next = curr;
                tail = curr;
            }
    
            return head;
        }
    
    双链接列表的目的是允许您在节点上进行正向和反向迭代。例如:

        void printfwd() {
            node *iter = head;
            while (iter != nullptr) {
                std::cout << ' ' << iter->data;
                iter = iter->next;
            }
            std::cout.put('\n');
        }
        void printrev() {
            node *iter = tail;
            while (iter != nullptr) {
                std::cout << ' ' << iter->data;
                iter = iter->prev;
            }
            std::cout.put('\n');
        }
    
    示例使用/输出

    $ ./bin/ll_double_int
    
    forward:
     1 2 3 4 5 6 7 8 9 10
    
    reverse:
     10 9 8 7 6 5 4 3 2 1
    

    检查一下,如果您还有其他问题,请告诉我。

    列表
    构造函数有UB。您正在将
    head
    设置为
    nullptr
    ,然后立即使用
    head->next
    。当我运行您的代码时,我遇到了一个分段错误(这比不打印列表的内容更令人担忧)。当我修复分段错误(UB)时,代码可以工作。它不太好,因为它忽略了
    tail
    ,但它确实打印了列表。
        void printfwd() {
            node *iter = head;
            while (iter != nullptr) {
                std::cout << ' ' << iter->data;
                iter = iter->next;
            }
            std::cout.put('\n');
        }
        void printrev() {
            node *iter = tail;
            while (iter != nullptr) {
                std::cout << ' ' << iter->data;
                iter = iter->prev;
            }
            std::cout.put('\n');
        }
    
    #include <iostream>
    
    class list;
    
    class node {
    public:
        int data;
        node *next;
        node *prev;
        friend class list;
    };
    
    class list {//double list 
        node *head;
        node *tail;
    public:
        list() { head = nullptr; tail = nullptr; }
        node *pushback (int newdata) {
            node *curr = new node;
            curr->data = newdata;
            curr->next = curr->prev = nullptr;
    
            if (head == nullptr)
                head = tail = curr;
            else {
                curr->prev = tail;
                tail->next = curr;
                tail = curr;
            }
    
            return head;
        }
        void printfwd() {
            node *iter = head;
            while (iter != nullptr) {
                std::cout << ' ' << iter->data;
                iter = iter->next;
            }
            std::cout.put('\n');
        }
        void printrev() {
            node *iter = tail;
            while (iter != nullptr) {
                std::cout << ' ' << iter->data;
                iter = iter->prev;
            }
            std::cout.put('\n');
        }
    };
    
    int main() {
    
        list test;
    
        for (int i = 1; i <= 10; i++)
            test.pushback(i);
    
        std::cout << "\nforward:\n";
        test.printfwd();
        std::cout << "\nreverse:\n";
        test.printrev();
    }
    
    $ ./bin/ll_double_int
    
    forward:
     1 2 3 4 5 6 7 8 9 10
    
    reverse:
     10 9 8 7 6 5 4 3 2 1