【问题标题】:How to print a simple linked list (C++)?如何打印一个简单的链表(C++)?
【发布时间】:2017-06-02 07:35:15
【问题描述】:

我做的代码是这样的:

struct node
{
    int value;
    node *prev;
    node *next;
};

void play()
{
    node *head = NULL, *temp = NULL, *run = NULL;

    for (int x = 1; x > 10; x++)
    {
        temp = new node();    //Make a new node
        temp -> value = x;    //Assign value of new node
        temp -> prev = NULL;  //Previous node (node before current node)
        temp -> next = NULL;  //Next node (node after current node)
    }
    if (head == NULL) 
    {
        head = temp; //Head -> Temp
    }
    else
    {
        run = head; //Run -> Head
        while (run -> next != NULL)
        {
            run = run -> next; //Go from node to node
        }
        run -> next = temp; //If next node is null, next node makes a new temp
        temp -> prev = run;
    }
    run = head; //Play from start again
    while (run != NULL)  //Printing
    {
        printf("%d\n", run -> value);
        run = run -> next;
    }
}


int main()
{
  play();
  system ("pause");
  return 0;
}

但是,它不起作用。没有输出(完全空白)。我怎样才能让这个链接列表正确打印?我希望它输出:

1 2 3 4 5 6 7 8 9 10

我的其他选择是为打印创建另一个单独的函数或将整个内容移动到 int main 但我已经尝试过了,它仍然没有输出任何内容。

【问题讨论】:

  • int x = 1; x > 10?
  • 你应该使用std::list。如果是作业,请编写自己的void output_list(struct node*list); 函数。在所有情况下,使用所有警告和调试信息进行编译(g++ -Wall -Wextra -g 和 GCC)并了解如何使用调试器 gdb。

标签: c++ loops for-loop linked-list doubly-linked-list


【解决方案1】:

对于初学者来说,函数中第一个 for 循环的条件有一个错字

for (int x = 1; x > 10; x++)
                ^^^^^^

应该有

for (int x = 1; x <= 10; x++)
                ^^^^^^

其次,尝试将新节点添加到列表中的代码位于 for 循环之外。所以只有最后分配的节点会被添加到列表中。您必须将代码放在循环中。

另外,如果这里是一个双链表,那么最好有一个尾节点,一个新节点将附加到该尾节点。

你应该在退出函数之前释放所有分配的内存。

该函数可以如下所示,如演示程序中所示。

#include <iostream>
#include <cstdlib>

struct node
{
    int value;
    node *prev;
    node *next;
};

void play()
{
    const int N = 10;
    node *head = nullptr, *tail = nullptr;

    for (int i = 0; i < N; i++)
    {
        node *temp = new node{ i + 1, tail, nullptr };

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

    for (node *current = head; current != nullptr; current = current->next)
    {
        std::cout << current->value << ' ';
    }
    std::cout << std::endl;

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

int main() 
{
    play();
    // system("pause");

    return 0;
}

程序输出是

1 2 3 4 5 6 7 8 9 10 

您可以通过添加一个参数来指定创建的列表中的节点数,而不是使用幻数10,从而使函数更加灵活。

例如

void play( int n )
{
    node *head = nullptr, *tail = nullptr;

    for (int i = 0; i < n; i++)
    {
        node *temp = new node{ i + 1, tail, nullptr };

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

    for (node *current = head; current != nullptr; current = current->next)
    {
        std::cout << current->value << ' ';
    }
    std::cout << std::endl;

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

在这种情况下,可以像这样调用函数

play( 10 );

或

play( 20 );

等等。

【讨论】:

    【解决方案2】:

    当您运行play() 时,您创建了 10 个新节点,但在创建新节点之前将它们存储在任何地方。因此,您“丢失”了所有节点 - 除了最后一个,它仍在 temp 中。

    相反,您应该执行以下操作:

    for (int x = 1; x < 10; x++)
    {
        if (temp == nullptr) {
            temp = new node();
            temp -> value = x;
            temp -> prev = nullptr;
            temp -> next = nullptr;
            head = temp;
        } else {
            temp -> next = new node();
            temp -> next -> value = x;
            temp -> next -> prev = temp;
            temp -> next -> next = nullptr;
            temp = temp -> next
        }
    }
    

    然后,您可以像以前一样打印您的链表:

    run = head; //Play from start again
    while (run != nullptr)  //Printing
    {
        printf("%d\n", run -> value);
        run = run -> next;
    }
    

    正如来自莫斯科的@Vlad 所指出的,在退出函数之前不要忘记释放分配的内存。

    请注意,我使用nullptr 而不是NULL。这是一个替换NULL 的C++11 关键字。解释是here。

    【讨论】:

    • 这也不会创建十个节点。
    • 对,我没有看到条件中的错误!固定;)
    【解决方案3】:

    首先,您的程序永远不会进入for 循环。您的循环相当于:

    int x=1;
    while(x>10) { // always false
      // do stuff
      x++;
    }
    

    因此,temp 是 NULL,head 被初始化为 NULL 并且没有任何反应。

    其次,您的列表的初始化不在循环中,因此最多只会初始化head。在函数末尾移动 for 循环的右括号(并调整缩进等)。

    第二次,如果你的编译器允许,你可以考虑使用更多的 C++ 习语而不是 C 习语(如果你的目标是学习 C++),使用nullptr、cout、智能指针...但这是另一个故事!

    【讨论】:

      猜你喜欢
      • 2015-08-28
      • 1970-01-01
      • 2016-06-15
      • 1970-01-01
      • 2021-01-23
      • 1970-01-01
      • 1970-01-01
      • 2011-09-17
      • 1970-01-01
      相关资源
      最近更新 更多