当前位置: 首页 > 知识库问答 >
问题:

双链接列表节点插入到底

刁跃
2023-03-14

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

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

我正在确定。新建节点首先检查头部是否有任何值

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

我将前一个节点连接到新节点,新节点指向前一个节点,而新节点指向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;
}

共有1个答案

李烨烁
2023-03-14

您已经正确地完成了很多事情,但对构造函数-

您对构造函数的直接问题,如注释中所示,是您将headled设置为nullptr,然后立即取消对headail的引用头自引用(仅在循环链表中需要)。

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

如果将headtail设置为nullptr,则没有指向有效节点的指针,因此无法取消引用该节点。您尝试设置头-

对于普通的非循环列表,只需省略设置head即可-

    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;

(注意:尾部指针是可选的,循环列表为头部。)-

由于您的问题涉及双链表,而不是循环列表,您只需设置head尾部等于添加第一个节点的新节点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-

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

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

不要养成坏习惯。为什么“使用命名空间std;”被认为是糟糕的做法?目前所有你必须处理的是coutendl,继续删除使用命名空间std;和简单的前缀coutendlstd::.

总而言之,你应该:

#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

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

 类似资料:
  • 我正在尝试为一个项目创建一个双链接列表容器。我不能使用任何std容器。必须对双链接列表进行排序。以下是我目前的代码: 我遇到的问题是在我的插入函数中。我正在使用调试器,并在以下行插入代码:list.insert(10);。 它正确地进入第一种情况,即head==nullptr并创建节点。当我进入下一行代码(list.insert(20))时,它会用这一行创建一个节点:node*node=newno

  • 我有以下代码,它是双链表实现的一部分。然后,我必须使用我的ADT实现来创建一个表,其格式为(它是一个字符串)、(它是uint32_t类型)(因此是一个2列的表)。 我需要首先创建这个表,然后添加到这个记录。 我的困难在于实现一个函数,该函数将要添加的值插入到这个特定的表中。我需要另一个插入功能,还是必须编辑我拥有的功能? 如果需要一个新的函数作为参数:一个指向结构类型的新表>代码> ListSt目

  • 该方法不起作用: 另一种有效的添加方法: 要调试的打印方法: DoublyLinkedList类: LinkedList和Node的实现非常简单,https://www.geeksforgeeks.org/doubly-linked-list/ 我首先创建一个link列表,insert_front()一个值来使头不为空,然后使用上面的方法插入其他东西。插入节点后的前端、结尾,但是,这个insert

  • 我有麻烦删除双向链表中的节点,程序崩溃,我不能解决这个问题。你能帮我吗?这是创建新节点,查看它们并删除它们的完整代码。 我认为这个问题与Node del的scanf()有关,但我不确定。当我只是通过或

  • 我遇到了一个问题,在这个问题中,您应该交换双链接列表中的一组节点。例如:对于列表