【问题标题】:Linked list shows only first node element on printing链表在打印时仅显示第一个节点元素
【发布时间】:2014-04-08 09:12:27
【问题描述】:

我正在尝试创建一个链表以增强我的指针和地址概念。我必须通过以下方式创建链表:

(1) 在终端一次读取所有节点。

(2) 然后显示最后形成的最终链表。

我如何尝试这样做? 我首先阅读链表的大小(要输入的节点总数)。然后我在do-while 循环中一一读取所有节点。阅读所有节点后,我尝试创建链表。我区分了以下情况:节点是由count 变量创建的第一个节点,当该节点是第一个节点时,该变量将具有count=0,之后它将处于另一个循环中。

我得到的输出如下:

 enter the size of node
4
start entering the number of elements until your size
2
3
4
5
Printing linked list
2-> //It don't print the other nodes, Just first one
hp@ubuntu:~/Desktop/pointer$ 

我这样做的完整代码是:

#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h> 
#include <string.h>

struct node 
{
    int freq;
    struct node * next;
};
typedef struct node node;
node * tree;

void main() 
{
    int size, data;
    int count = 0; //this count flag is to check is it's first node or not inside the do-while loop.
    tree = NULL;
    printf("enter the size of node\n");
    scanf("%d", & size);
    printf("start entering the number of elements until your size\n");
    node * temp3 = tree;
    node * prev;
    //Problem creating area is below
    do
    {
        scanf("%d", & data);
        if (count == 0)
        {
            node * temp;
            temp = (node * ) malloc(sizeof(node));
            temp-> freq = data;
            temp-> next = NULL;
            prev = temp;
        } 
        else if (count != 0) 
        {
            node * temp;
            temp = (node * ) malloc(sizeof(node));
            temp-> freq = data;
            temp-> next = NULL;
            prev-> next = temp;
        }
        size--;
        ++count;
    }
    while (size > 0);

    printf("Printing linked list\n");
    node * temp1;
    temp1 = prev;
    //there may be problem here
    while (temp1-> next != NULL) 
    {
        printf("%d-> ", temp1-> freq);
        temp1 = temp1-> next;
    }
    printf("\n");
}

谁能帮我打印完整的链接列表,指出解决方案的错误?

【问题讨论】:

  • 这里有几点注意事项:main 应该返回一些东西或设置为 void,据我计算,你有三个未使用的指针(tree、temp3 和 store),并且在你的 else if 中,你正在设置prev 节点到 temp,然后为 temp 分配内存并基本上覆盖它指向的内容。
  • 调试器,调试器,调试器...
  • @JamesHostick 我在编辑中保留了 void main() 。但问题是如何避免这种节点的覆盖,因为我正在一起读取所有节点
  • 我会说从将大量代码拆分为多个函数开始。
  • 另外,最好不要使用 void main(),只使用 int main()。

标签: c algorithm data-structures linked-list singly-linked-list


【解决方案1】:

好的,有一些不必要的指针和一些指针错误,为了方便回答我已经重写了你的代码,我将尝试解释我在这里做了什么:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>

struct node
{
    int freq;
    struct node * next;
};
typedef struct node node;
//only need two pointers when building a linked list, one for the top and one for the
//current node
node *tree = NULL, *curr = NULL; //init both pointers to NULL initially

int main()
{
    int size, data; //dont need count, you'll see in a minute why
    printf("enter the size of node\n");
    scanf("%d", & size);
    printf("start entering the number of elements until your size\n");

    //Problem creating area is below
    do
    {
        scanf("%d", &data);
        if (tree == NULL) //just test for top node being NULL instead of using count
        {
            node *temp;
            temp = malloc(sizeof(node));
            temp->freq = data;
            temp->next = NULL;
            //stylistically i like using curr rather than prev, just a style choice
            tree = temp; //set tree to first node
            curr = tree; //make the top node the current node
        }
        else //don't need else if, there are only two conditions
        {
            node *temp = malloc(sizeof(node));
            temp->freq = data;
            temp->next = NULL;
            curr->next = temp; //set the next node in list to the new one
            curr = curr->next; //here's where you had pointer issues, move the current
                               //to the newly created node
        }
        size--;
    }
    while (size > 0);

    printf("Printing linked list\n");
    curr = tree; //reuse curr, no need to make a new pointer

    //test for the current node being NULL, takes care of special case of empty list
    //causing a segfault when you attempt to access a member of an invalid pointer
    while (curr != NULL)
    {
        printf("%d->", curr->freq);
        curr = curr->next; //move to next item in list
    }
    printf("\n");
    return 0;
}

我运行了一个大小为 3 且输入为 1、2 和 3 的样本运行,我得到输出:1->2->3->

【讨论】:

  • 我没有对 malloc 进行任何错误测试,但是最好在 malloc 之后立即测试指针以确保它分配了内存,否则您应该打印某种错误消息。
  • 没问题,我喜欢指针,我讨厌指针,我又爱讨厌指针。
  • 为什么我们需要通过执行“curr = curr->next”将 cur 移动到新节点?我们已经通过 "curr->next = temp;" 行建立了 cur 到新节点的链接这一步应该足以加入两个节点之间的链接。你能详细解释一下吗?谢谢
  • curr 的目的是跟踪您当前在列表中的位置。 curr->next = temp 行将新创建的节点添加到列表的末尾。然后 curr = curr->next 将你当前的位置移动到列表中的最后一个节点,也就是我们刚刚追加到列表末尾的新节点。否则,您最终将覆盖当前节点而不是追加到末尾(这就是为什么您最终在列表中只有一个节点,而不管您让用户输入了多少元素)。
  • @JamesHostick 感谢另一个疑问,while (curr != NULL) 和 while (curr->next!= NULL) 有什么区别?,我试图通过打印结果来知道while (curr->next != NULL) 的情况下,它不会打印最后一个元素。但它应该这样做,因为我们一直在这样做,直到最后一个节点的下一个节点不为 NULL。
【解决方案2】:

你有两个问题。

else if (count != 0) 
    {
        node * temp = prev;
        temp = (node * ) malloc(sizeof(node));
        temp-> freq = data;
        temp-> next = NULL;
        prev-> next = temp;
    }

您没有将 prev 更改为指向您的新节点。在您的场景中它仍然指向“2”,并且列表中的节点永远不会超过两个。

试试类似的东西

else if (count != 0) 
    {
        /* node * temp = prev; */ //This code is not doing anything useful
        temp = (node * ) malloc(sizeof(node));
        temp-> freq = data;
        temp-> next = NULL;
        prev-> next = temp;
        prev = temp;
    }

接下来,你的打印循环应该是

node* temp1 = start; //You need a variable that points to the first node in the list
do 
{
    printf("%d-> ", temp1-> freq);
    temp1 = temp1-> next;
} 
//The last item will always have next == NULL, and must be included
while (temp1-> next != NULL); 

【讨论】:

  • 这里要注意第三块代码,当访问结构指针的成员时,您应该在访问之前检查以确保指针有效。否则你会得到一个段错误。只要 start 是一个有效的指针,它就不会发生,但你永远不能确定用户没有搞砸。 :)
  • @Archa 谢谢,但我试过你刚才说的,它们都不起作用
  • 我没有使用“start”,我使用的是“tree”。
猜你喜欢
  • 2019-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
相关资源
最近更新 更多