如何打印一个简单的链表(C++)?

Posted

技术标签:

【中文标题】如何打印一个简单的链表(C++)?【英文标题】:How to print a simple linked list (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 【参考方案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++;

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

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

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

【讨论】:

以上是关于如何打印一个简单的链表(C++)?的主要内容,如果未能解决你的问题,请参考以下文章

用 C++ 制作一个简单的链表

C++ - 使用 std::list,如何打印对象私有成员的链表?

创建一个非常简单的链表

如何打印包含路径目录(环境变量)的链表?

如何使用C++ STL中的链表list

c++堆与栈的简单认识