最后插入双向链表节点

问题描述 投票:0回答:1

我正在尝试创建一个函数,以便在最后添加双链表。我无法查明为什么它不打印任何内容。

构建程序时没有出现错误。

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

  1. 在前一个当前指针之后创建的指针

  2. 我将上一个节点连接到新节点,新节点指向上一个节点,而新节点则指向下一个nullptr。

#include "pch.h"
#include <iostream>

using namespace std;

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; head->next = tail; tail->prev = head;}
    node* pushback(int newdata) {
        node* curr = new node;
        curr->data = newdata;
        curr->next = nullptr;
        if (head == nullptr) {
            head = curr;
            return head;
        }
        node*precurr = head;
        while (precurr->next != nullptr){
            precurr = precurr->next;
        }
        precurr->next = curr;
        curr->prev = precurr;
        return head;
    }
    void print() {
        while (head->next != nullptr) {
            cout << head->data << " " << endl;
            head = head->next;
        }
    }
};

int main()
{
    list test;

    test.pushback(1);
    test.pushback(2);
    test.pushback(3);
    test.pushback(4);
    test.pushback(5);
    test.pushback(6);

    test.print();

    return 0;
}
c++
1个回答
0
投票

您已经正确完成了很多事情,但是您对构造函数以及对->prevtail指针的使用感到困惑。

如注释中所述,您的构造函数立即出现问题,是您将headtail设置为nullptr,然后立即取消引用headtail尝试使headtail ]自引用(仅在circularlinked-list中需要)。

list(){ head = nullptr; tail = nullptr; head->next = tail; tail->prev = head;}

headtail设置为nullptr,您没有指向有效node的指针,无法对其进行取消引用。您尝试设置head->next = tail; tail->prev = head;的操作立即失败,导致出现SegFault。

出于在普通非圆形列表中的目的,您只需在构造函数中省略设置head->nexttail->prev,例如

    list() { head = nullptr; tail = nullptr; }

如果要使列表成为循环列表,则将headtail自引用为:

    node *pushback (int newdata) {
        ...
        if (head == nullptr)     /* for circular-list 1st node initialization */
            head = tail = head->prev = head->next = tail->prev = tail->next = curr;

((note: tail指针对于circular列表是可选的,因为head->prev始终指向列表中的最后一个节点)

由于您的问题属于双链表而不是循环列表,因此您只需要将headtail都设置为等于新节点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指针通过设置tail = curr;到新的终端节点,例如

        else {
            curr->prev = tail;
            tail->next = curr;
            tail = curr;
        }

        return head;
    }

double-linked-list的目的是允许您在节点上进行正向和反向迭代。例如:

    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');
    }

(对于循环列表,迭代方案略有不同,因为您可以从任何节点进行正向和反向迭代,而无需从headtail开始。要插入循环列表,只需简单地插入一个新的tail节点)。

不要养成不良习惯。 Why is “using namespace std;” considered bad practice?当前您需要处理的只是coutendl,继续删除using namespace std;,只需在coutendl前面加上std::

完全将其放入:

#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

仔细检查,如果还有其他问题,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.