简体   繁体   English

有人可以帮我处理这个链表吗? C++

[英]Can someone help me with this linked list? C++

I have an object oriented exam tomorrow and I'm still stuck with linked lists.我明天有一个面向对象的考试,但我仍然坚持使用链表。 For some reason I cant quite understand how they work or how to implement them properly.出于某种原因,我不太明白它们是如何工作的或如何正确实施它们。 I've watched a lot of videos and tutorials but it still is quite complex.我看过很多视频和教程,但它仍然很复杂。 I always get an error which prints nothing to the console, just a blank black page.我总是收到一个错误,它不会向控制台打印任何内容,只是一个空白的黑页。 Can someone tell em what am I doing wrong?有人可以告诉他们我做错了什么吗? Thank you.谢谢你。

#include <iostream>
#include <string>

using namespace std;

struct node
{
    string name;
    int number;
    node* next;
};
struct node* head = 0;

class Employees
{
private:
    node* head, * tail;
public:
    Employees()
    {
        head = NULL;
        tail = NULL;
    }
    void addToList(string Name, int Num)
    {
        node* n = new node;
        n->name = Name;
        n->number = Num;
        n->next = NULL;
        if (head == NULL)
        {
            head = n;
            tail = n;
        }
        else
        {
            tail->next = n;
            tail = tail->next;
        }
    }
    void PrintAll()
    {
        while (head != NULL)
        {
            node* current;
            while (current != NULL)
            {
                cout << current->name << "\t";
                cout << current->number;
            }
        }
    }
};

int main()
{
    Employees a;
    a.addToList("Robert", 54);
    a.addToList("Manny", 77);

    a.PrintAll();

}

You have issue with你有问题

  1. PrintAll where Head is unaltered and makes it infinite loop. PrintAll其中HeadPrintAll并使其无限循环。
  2. current is uninitialised and accessing it as a pointer is UB current未初始化并作为指针访问它是 UB

Below snippet shoud fix your problem,下面的代码段应该可以解决您的问题,

void PrintAll()
{
    node* temp = head;
    while (temp != nullptr)
    {
       std::cout << temp ->name << "\t";
       std::cout << temp ->number;
       temp = temp->next            
    }
}

The primary problem with your code is that your PrintAll method is written incorrectly and you never update your current pointer.您的代码的主要问题是您的PrintAll方法编写不正确,并且您从未更新current指针。 Perhaps you've not been taught for loops yet, but this is an ideal case for them:也许你还没有学过for循环,但这对他们来说是一个理想的例子:

for(node* current = head; current != NULL; current = current->next) {
  cout << current->name << "\t" << current->number;
}

The first part of the for loop initialises the variable (which you neglected to do in your code), the next is the end condition (as you'd find in a while loop), and the third part updates the variable each cycle through the loop thus traversing your loop from start to end. for 循环的第一部分初始化变量(您在代码中忽略了这一点),接下来是结束条件(正如您在while循环中发现的那样),第三部分在每个循环中更新变量循环从而从头到尾遍历您的循环。

You can do all this with a while loop but it expresses your intent less clearly, so a for loop should be preferred.您可以使用while循环来完成所有这些,但它表达的意图不太清楚,因此应该首选for循环。 I am also not sure why you have a while loop checking whether head is null?我也不知道为什么你有一个while循环检查head是否为空? Since it does not change during the loop, there is no need to repeatedly check it, and - in any case - there is no advantage to checking it separately as opposed to simply checking current once it has been initialised to head .因为它在循环期间不会改变,所以没有必要重复检查它,并且 - 在任何情况下 - 单独检查它与在它初始化为head简单地检查current相比没有优势。

As a minor note, if you're using a modern C++ version, nullptr should be preferred over NULL .需要注意的是,如果您使用的是现代 C++ 版本,则nullptr应该优于NULL

Three issues:三个问题:

while (head != NULL)
{
    /*...*/
}

You do not modify head inside the loop (why would you), hence this loop would run either never or forever.您不会在循环内修改head (为什么要这样做),因此该循环将永远运行或永远运行。

Second:第二:

 node* current;
 while (current != NULL)

current in uninitialized. current未初始化。 Comparing it to NULL invokes undefined behavior.将其与NULL进行比较会调用未定义的行为。 Always initialize your variables!始终初始化您的变量!

Last:最后的:

while (current != NULL)
{
    cout << current->name << "\t";
    cout << current->number;
}

Similar to the first issue, the loop condition is either true or false , but it never changes, ie the loop either runs never or infinite.与第一个问题类似,循环条件为truefalse ,但它永远不会改变,即循环要么永不运行,要么无限运行。

As this appears to be an exercise, I'll leave it to you to fix the code.由于这似乎是一个练习,我将把它留给您来修复代码。

For starters this declaration in the global namespace对于初学者来说,全局命名空间中的这个声明

struct node
{
    string name;
    int number;
    node* next;
};
struct node* head = 0;
^^^^^^^^^^^^^^^^^^^^^

is redundant and is used nowhere.是多余的,无处使用。 Remove it.去掉它。

It is better to make the structure node an inner member of the class Employees.最好使结构节点成为Employees 类的内部成员。 For example例如

class Employees
{
private:
    struct node
    {
        string name;
        int number;
        node* next;
    } *head = nullptr, *tail = nullptr;
    //...   

The constructor does nothing special.构造函数没有什么特别的。 So it can be defined as a default constructor.因此可以将其定义为默认构造函数。

 Employees() = default;

Th function addToList should accept the first argument by constant reference函数addToList应该通过常量引用接受第一个参数

void addToList( const string &Name, int Num )
                ^^^^^^^^^^^^^^^^^^

The function PrintAll has an infinite loop when the pointer head is not a null pointer当指针头不是空指针时,函数PrintAll会无限循环

void PrintAll()
{
    while (head != NULL)
    {
        //...
    }
}

and moreover it invokes undefined behavior because the used pointer current was not initialized而且它会调用未定义的行为,因为使用的指针电流未初始化

node* current;
while (current != NULL)

The function should be declared with the qualifier const because it does not change the list itself.该函数应使用限定符 const 声明,因为它不会更改列表本身。

Also you need a destructor to free the dynamically allocated memory for nodes.您还需要一个析构函数来释放节点的动态分配内存。 Also you could suppress the copy construction and assignment.您也可以禁止复制构造和分配。

Here is a demonstrative program that shows how the class can be implemented.这是一个演示程序,展示了如何实现该类。

#include <iostream>
#include <string>

using namespace std;

class Employees
{
private:
    struct node
    {
        string name;
        int number;
        node* next;
    } *head = nullptr, *tail = nullptr;

public:
    Employees() = default;

    ~Employees()
    {
        while ( head != nullptr )
        {
            node *tmp = head;
            head = head->next;
            delete tmp;
        }
        tail = nullptr;
    }

    Employees( const Employees & ) = delete;
    Employees & operator =( const Employees & ) = delete;

    void addToList( const string &Name, int Num )
    {
        node *n = new node { Name, Num, nullptr };

        if ( head == nullptr )
        {
            head = n;
            tail = n;
        }
        else
        {
            tail->next = n;
            tail = tail->next;
        }
    }

    void PrintAll() const
    {
        for ( node *current = head; current != nullptr; current = current->next )
        {
            cout << current->name << ' ';
            cout << current->number << '\t';
        }
    }
};

int main()
{
    Employees a;
    a.addToList( "Robert", 54 );
    a.addToList( "Manny", 77 );

    a.PrintAll();

    cout << endl;
}

The program output is程序输出是

Robert 54   Manny 77

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM