【问题标题】:Printing elements of a linked list, but instead, it prints reversed C++打印链表的元素,但相反,它打印反向 C++
【发布时间】:2020-09-29 17:35:00
【问题描述】:

这里我只是想打印我创建的链表的元素,但它以反向顺序打印列表。看起来代码有错误。帮我解决它 每次我们输入要插入链表的元素时,push 函数都会将节点添加到链表中。我已经传递了头和数据的引用。每次调用 push 函数时都会动态创建一个节点。我这里用的是c++。

#include<iostream>
using namespace std;
class node{
    public:
    int data;
    node* next;
};
//creating linked list 
    void push(node** head_ref,int new_data) //passing address of head and data to put in list
    {

        node* new_node=new node(); //new node created
        new_node->data=new_data;   //data inserted
        new_node->next=*(head_ref);
        *(head_ref)=new_node;
    }

int main()
{
    node* head=NULL;

    int n;
    cin>>n; //number of elements in linked list
    for(int i=0;i<n;i++)
    {
        int val;
        cin>>val;
        push(&head,val); //push function which creates a linked list

    }

//while loop for printing elements of linked list
        while(head!=NULL)
        {
            cout<<head->data;
            head=head->next;
        }

    return 0;
}

【问题讨论】:

  • 不,您正在以相反的顺序创建列表。仔细查看新节点的附加位置。
  • 你所做的总是在新的头部之前,这意味着“向后”填充列表,即最后一个元素被推到最后一个头部的前面。相反,尝试分配 (*head_ref)->next=new_node

标签: c++ data-structures linked-list singly-linked-list


【解决方案1】:

您当前所做的是将每个节点分配为当前头的前任,因此最终您的头将是您添加的最新元素,其后继是倒数第二个元素,其后继是倒数第三个元素,等等。从而产生一个反向列表。

您应该将新节点分配为当前“头”的继任者,如下所示:

void push(node** tail_ref,int new_data) //passing address of tail and data to put in list
{
    node* new_node=new node(); //new node created
    new_node->data=new_data;   //data inserted
    (*tail_ref)->next= new_node;
    *(tail_ref)=new_node;
}

请注意,我在上面的 sn-p 中将 head_ref 重命名为 tail_ref,这更好地描述了指针实际表示的内容:指向列表当前最后一个元素的指针,因此是列表的尾部。

当然,您需要保存指向第一个元素的指针。否则你将无法遍历你的链表。

【讨论】:

    【解决方案2】:

    Simon 的答案的扩展,到目前为止是正确的:

    您已经有一个类“节点”——为什么不也创建一个类“列表”或“链接列表”:

    class LinkedList
    {
        node* m_head = nullptr;
        node* m_tail = nullptr;
    };
    

    现在您总是将头和尾组合在一起,无需单独存储。请注意,在上面的示例中,它们都是 private。这实际上就是你应该如何设计你的课程。如果你不这样做,那么你允许用户从外部破坏列表实现(例如,有人可能只是将这些指针之一设置为 nullptr,从而在 head 的情况下产生内存泄漏)。

    但是,现在您必须提供适当的方法来访问和修改列表:

    class LinkedList
    {
    public:
        void append(int new_data);  // as Simon proposed
        void prepend(int new_data); // your implementation
        int head();
        int tail();
        void dropHead();
        //void dropTail(); // is an O(n) operation with singly linked list, though!
    private:
        node* m_head = nullptr;
        node* m_tail = nullptr;
    };
    

    节点类与您的列表非常密切相关,您可能会考虑不要让它成为一个独立的类,而是让它成为一个嵌套类。还有很多东西要添加(例如,如何遍历列表)。为了获得一些提示,我建议先了解一下 STL 并熟悉迭代器的概念。

    最后:停止重新发明轮子。 STL 已经提供了完全实现的双 (std::list) 和单 (std::forward_list) 链表。可以尝试自己的实现来了解风向,但是一旦你知道了,就切换回 STL。

    【讨论】:

      猜你喜欢
      • 2020-09-05
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-19
      • 1970-01-01
      相关资源
      最近更新 更多