【问题标题】:Problem in implementing a linkedlist in c++在 C++ 中实现链表的问题
【发布时间】:2021-06-28 05:32:19
【问题描述】:

我正在学习 C++ 并尝试实现单链表。基本上是一个链表,提供两种简单的方法,插入和显示。下面是代码sn -p --

class LinkedList {


public:
    int data;
    LinkedList *next;
    LinkedList() {

    }

    LinkedList(int d) {
        data = d;
        

    }

    void insert(int d) {
        LinkedList temp = *this;
        cout << "Calling insert "<< temp.data;
        while (temp.next != NULL) {
            cout << "Inside the while loop"<< temp.data;
            temp = *temp.next;

        }           
        temp.next = new LinkedList(d);      

        


    }

    void display() {
        LinkedList temp = *this;
        cout << temp.data;          
        

        while (&temp != NULL) {             
            cout << temp.data;    
            temp = *temp.next;
            cout << temp.data;              
        } 
        


    } 




};



int main()
{
    LinkedList head(1);
    head.insert(2);
    head.insert(3);
    head.insert(4);
    head.display();

    return 0;
}

但是,此插入方法未按预期工作。即使在多次调用 insert 之后,它也永远不会进入 while 循环,并且永远不会打印“在 while 循环内”。你能指导一下我的插入方法有什么问题吗?

【问题讨论】:

  • LinkedList temp = *this; 制作一个副本,然后您修改该副本。
  • 但是,此插入方法未按预期工作 -- 您未能在两个构造函数中初始化 所有 成员变量,并且这只是众多问题之一。 int main() { LinkedList x; x.insert(10); } -- 您不需要任何其他代码来查看问题。
  • LinkedList temp = *this; 创建this 的本地副本。因此,temp.next = new LinkedList(d); 将新节点附加到本地副本,并在您离开 insert() 后立即丢失。

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


【解决方案1】:

你必须改进不止一件事来保持代码运行。

  1. 在构造函数中初始化next的值。否则,您无法确定在创建 LinkedList 时将 next 设置为 NULL

    LinkedList(int d) : data(d), next(NULL) {}
    
  2. 使用LinkedList* 而不是LinkedList 作为temp 类型。否则,您不会修改列表节点,而是修改第一个节点的本地副本。请注意:

    • LinkedList temp = *this; 必须替换为 LinkedList* temp = this;
    • 所有出现的temp.next 都必须替换为temp-&gt;next
    • 所有出现的temp.data 都必须替换为temp-&gt;data
    • display 函数中的 while 条件必须替换:&amp;temp != NULL -> temp != NULL
  3. display 函数的 while 循环中的第三行必须删除,因为temp 可能指向NULL

次要问题是您没有在输出中换行。请务必在您希望断行的地方添加&lt;&lt; endl

最大的问题是你仍然需要为LinkedList 实现析构函数来释放分配的资源。根据rule of three,使用析构函数还应该定义复制构造函数和赋值运算符。

另一种方法是使用像std::unique_ptr 这样的智能指针来存储下一个节点的地址。

#include <iostream>
#include <memory>

using namespace std;

class LinkedList {
public:
    int data;
    std::unique_ptr<LinkedList> next;

    LinkedList(int d) : data(d) {}

    void insert(int d) {
        LinkedList* temp = this;
        cout << "Calling insert "<< d << std::endl;
        while (temp->next) {
            cout << "Inside the while loop: "<< temp->data << std::endl;
            temp = temp->next.get();

        }           
        temp->next = std::make_unique<LinkedList>(d);      
    }

    void display() {
        LinkedList* temp = this;
        
        while (temp != NULL) {             
            cout << temp->data << std::endl;
            temp = temp->next.get();
        } 
    } 
};

int main()
{
    LinkedList head(1);
    head.insert(2);
    head.insert(3);
    head.insert(4);
    head.display();

    return 0;
}

【讨论】:

  • 在 C++11 及更高版本中,应使用nullptr 而不是NULL
猜你喜欢
  • 2020-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-18
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
相关资源
最近更新 更多