循环双链表C++

Circularly double linked list C++

本文关键字:C++ 链表 循环      更新时间:2023-10-16

我想要实现一个循环的双链表。该列表只包括传入字符串对象中的这些字符这是我的代码,但我总是有seg错误。我用一个伪头作为这个列表

#ifndef MY_LIST_H
#define MY_LIST_H
#include <string>
#include <iostream>
using namespace std;
/**------   -----------------
* dummy |->|pred|value|next|
* ------   -----------------
* */

struct Node
{
char value;
Node *next;
Node *pred;
Node( char value): value(value), next(0), pred(0){};
};
class MyList
{
private:
Node* head;
unsigned int count; // count number of node
public:
// default constructor
MyList(): count(0)
{
head = new Node('P');
}
//Constructs a list from a passed-in string object,
MyList(const string& str): count(0)
{
Node *cur = head;
if(count == 0)
{
head-> pred = head;
head-> next = head;
}
else
{
for( unsigned i =0; i< str.length(); ++i)
{
cur->next = new Node(str.at(i));
Node *temp = cur->next;
temp-> pred = cur;
++count;
if(count == str.length())
{
cur->next->next = head;
head-> pred = cur-> next->pred;
}
}
}
}
void print() const
{
Node *cur = head->next;
while( cur != head)
{
cout << cur-> value;
cur = cur-> next;
}
}
};
#endif

您似乎不太了解构造函数。

初始化类时只调用一个构造函数。如果你愿意,你可以从另一个构造函数调用构造函数,但这不是默认的:我可以在C++中从另一种构造函数调用构造函数吗(进行构造函数链接)?。

在您的实例中,您的第二个构造函数可能应该是这样的:MyList(const string& str): MyList() { ... }

这样head将被正确地初始化,并且不会创建segfault。

此外,您可以在调试模式下在调试器中运行代码,并找出代码崩溃的行。标头中的using namespace ...;也是一种糟糕的做法,因为您不知道标头将包含在哪里。

如果不了解如何使用这些类,很难确切地说出发生了什么,但您的MyList构造函数在字符串上重载,马上就坏了。它将count设置为0,这样您就知道它将始终进入if子句,而不会进入else

MyList(const string& str): count(0)
{
Node *cur = head;
if(count == 0)
{
head-> pred = head;
head-> next = head;
}
else . . .

在if语句中,它试图取消引用从未被赋值的head。你确实在默认构造函数中设置了它,但这个构造函数似乎也不做任何其他事情。

构造函数的目的是从头开始构造一个有效的对象。有时,一个构造函数重载可能会委托给另一个以避免重复代码,但我不确定您在这里要做什么。

假设第二个构造函数实际上是一个helper方法,那么它仍然不起作用,因为count永远不会超过零(除了在else子句中,但使用count==0无法实现)。

我承认我没有仔细看,但我猜如果执行到目前为止:

cur->next->next 

当你试图访问它时,它并不总是会被设置。如果cur->next是nullptr,那么你的程序就会死亡。