有人能帮我处理这个链接列表吗?C++



我明天要参加面向对象的考试,但我仍然被链表所困扰。出于某种原因,我不太明白它们是如何工作的,也不太明白如何正确实施它们。我看了很多视频和教程,但它仍然很复杂。我总是收到一个错误,它不会向控制台打印任何内容,只是一个空白的黑色页面。有人能告诉他们我做错了什么吗?非常感谢。

#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();
}

您的有问题

  1. PrintAll,其中Head不变并使其无限循环
  2. current未初始化,作为指针访问它是UB

下面的片段应该解决你的问题,

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

对于初学者来说,这个声明在全局命名空间中

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

是多余的,无处使用。移除它。

最好使结构节点成为Employees类的内部成员。例如

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

构造函数没有做什么特别的事情。因此,它可以被定义为默认构造函数。

Employees() = default;

函数addToList应通过常量引用接受第一个参数

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

当指针头不是空指针时,函数PrintAll具有无限循环

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

此外,它调用未定义的行为,因为使用的指针电流没有初始化

node* current;
while (current != NULL)

函数应该用限定符const声明,因为它不会更改列表本身。

此外,您还需要一个析构函数来为节点释放动态分配的内存。也可以取消复制构造和指定。

下面是一个演示程序,展示了如何实现类。

#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;
}

程序输出为

Robert 54   Manny 77

代码的主要问题是PrintAll方法写得不正确,并且从未更新current指针。也许您还没有学习过for循环,但这是它们的理想情况:

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

for循环的第一部分初始化变量(您在代码中忽略了这一点(,下一部分是结束条件(正如您在while循环中发现的那样(,第三部分在循环的每个循环中更新变量,从而从头到尾遍历循环。

您可以使用while循环来完成所有这些操作,但它表达的意图不太清楚,因此应该首选for循环。我也不确定为什么你有一个while循环来检查head是否为空?由于它在循环过程中不会改变,因此不需要重复检查它,而且在任何情况下,单独检查它都没有好处,而不是在current初始化为head后简单地检查它。

需要注意的是,如果您使用的是现代C++版本,nullptr应该优先于NULL

三个问题:

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

您没有在循环中修改head(为什么要修改(,因此此循环将永远或永远运行。

第二:

node* current;
while (current != NULL)

current未初始化。将其与NULL进行比较会调用未定义的行为。始终初始化变量!

上一篇:

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

与第一个问题类似,循环条件是truefalse,但它从未改变,即循环要么从不运行,要么无限运行。

由于这似乎是一个练习,我将由您来修复代码。

相关内容

  • 没有找到相关文章

最新更新