C++双向链表打印

C++ Doubly linked list printing

我在使用双向链表时遇到了一些困难 class,这是我大学项目的一部分。 class的代码是这样的:

class container
{
public:
    class node
    {
        public:
        node * prev;
        node * next;
        int value;
    };

container(int v);

node *start; // first element of the list
node *finish; // last element of the list
void insert_start(node *start, int val);
void print_container(); 
}

函数insert_start 应该将元素添加到列表的开头。代码如下:

void container :: insert_start(node *start, int val)
{
    if(start!=NULL)
    {
        cout << "in insert_start" << endl;
        cout << "number added:" << val << endl;

        node *element = new node;

        element->value=val;
        element->next=start;
        start=element;
        start->prev=NULL;
    }
    else
    {
        cout << "List is empty" << endl;
    }
}

函数 print_container 应该打印我的链表。代码如下所示:

void container::print_container()
{
    node *tmp;
    tmp = start;
    while(tmp!=nullptr)
    {
        cout << tmp->value << endl;
        tmp=tmp->next;
    }
}

不幸的是,我的程序有两个问题。首先,它 似乎在数据结构的添加元素中添加了相同的随机值。其次,在执行函数 print_container 时出现段错误。我想这可能是 insert_start 函数中的一个(或多个)错误,但我对此并不完全确定。

这里是测试程序:

int main(void)
{
    int how_many_pieces;

    container L(6);

    L.insert_finish(L.finish,3);
    cout << "added element: " << L.finish->value << endl;

    L.insert_start(L.start,8);
    cout << "added element: " << L.start->value << endl;

    L.insert_start(L.start,12);
    cout << "added element: " << L.start->value << endl;


   //show elements of the L list
   L.print_container();
   cout << "\n";

return 0;
}

感谢您的帮助。

在此代码中:

void container :: insert_start(node *start, int val)
{
    if(start!=NULL)

最后一行 start 应该指的是哪一行?是检查参数值,还是 public class 值?

另外,如果列表是空的,您可能想要做一些除了打印消息以外的事情。该列表必须以某种方式开始


(附录)

至少有两种方法可以防止这个问题。我将同时显示三个:

void container :: insert_start(node *node_to_insert, int val)
{
    if (this->start != NULL)  // is list not empty?

看起来差不多吧?

  • 形式参数名称现在表明其含义。顾名思义就是将指向的节点添加到链表中。
  • 对象实例值通过 this 关键字访问。这在语法上消除了同名变量范围的歧义,真正帮助程序员轻松识别什么是什么。
  • 评论阐明了声明的高级意图,这使得任何检查代码的人都可以轻松识别可能的差异。
  • 参数名称不再匹配对象成员名称。虽然让名称彼此平行(p_x, p_y, p_z 用于初始化成员变量的三个参数值 x, y, z)通常很有用,但为了简单明了,它们确实应该保持不同。

首先,不要将节点作为参数传递 - 您不需要这样做。容器 class 已经可以看到开始节点和结束节点,将它们传入只会混淆事情。

其次,您应该将这些设置为私有,以便使用 class 的任何人都必须使用您的 insert_start 或 insert_finish 功能。

新的 class 将如下所示:

class container
{
    private:
        class node
        {
            public:
            node * prev;
            node * next;
            int value;
        };

        node *start; // first element of the list
        node *finish; // last element of the list

    public:
        container(int v);

        void insert_start(int val);
        void print_container();
};

第三,确保为每个方向设置链接。例如,在您的 insert_start 函数中:

node *element = new node;

element->value = val;
element->next = start;
element->prev = NULL;
start->prev = element; //This part was missing
start = element;

在不将原始节点引用回新节点的情况下,您将其视为正常的 singly-linked 列表。如果您想要 doubly-linked 列表提供的遍历灵活性,您需要正确设置链接。