【问题标题】:What is wrong with my Singly Linked List implementation?我的单链表实现有什么问题?
【发布时间】:2017-11-28 22:26:32
【问题描述】:

这是实现单链表的尝试。
问题是当尝试使用while (traverse != NULL) 打印列表时,程序输出1,第一个节点的数据,但不打印所有其他节点的数据。我是否错误地链接了节点,如果是,在哪里?

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

typedef struct node {
    int data;
    struct node *next;
} Node;

struct node *root;

int main(void) {
    Node *list, *traverse;
    /* root will always be the first of the list */
    root = malloc(sizeof(*list));

    list = root;

    list->data = 1;
    list->next = NULL;
    list = list->next;

    list = malloc(sizeof(*list));
    list->data = 2;
    list->next = NULL;
    list = list->next;

    list = malloc(sizeof(*list));
    list->data = 3;
    list->next = NULL;
    list = list->next;

    list = malloc(sizeof(*list));
    list->data = 4;
    list->next = NULL;
    list = list->next;

    list = malloc(sizeof(*list));
    list->data = 5;
    list->next = NULL;
    list = list->next;

    traverse = root;

    while (traverse != NULL) {
        printf("%d\n", traverse->data);
        traverse = traverse->next;
    }   
    return 0;
}

输出:

$ gcc main.c && ./a.out
1


预期输出:

$ gcc main.c && ./a.out
1
2
3
4
5

更新: 正如大家所建议的那样,我已经更新了我的源文件:

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

typedef struct node {
    int data;
    struct node *next;
} Node;

struct node *root;

int main(void) {
    Node *list, *traverse;
    /* root will always be the first of the list */
    root = malloc(sizeof(*list));

    list = root;

    list->data = 1;
    list->next = malloc(sizeof(*list));

    list = list->next;
    list->data = 2;
    list->next = malloc(sizeof(*list));

    list = list->next;
    list->data = 3;
    list->next = malloc(sizeof(*list));

    list = list->next;
    list->data = 4;
    list->next = malloc(sizeof(*list));

    list = list->next;
    list->data = 5;
    list->next = NULL;

    traverse = root;

    while (traverse != NULL) {
        printf("%d\n", traverse->data);
        traverse = traverse->next;
    }   
    return 0;
}

非常感谢大家!

【问题讨论】:

    标签: c linked-list singly-linked-list


    【解决方案1】:

    只需针对这两个语句重新检查您的代码即可:

    list->next = NULL; list = list->next;

    这里的list->next 指向NULL。你指向 list = list->next;你的假设在这里是不正确的。因此,您没有正确获取下一个元素。

    首先为 list->next 分配内存,然后尝试指向那里。理想情况下,这不是我做事的方式。但是,为了纠正您的逻辑,我正在编写以下代码行:

    list->data = 1;
    list->next = malloc(sizeof(*list));
    list = list->next;
    

    您必须为每个节点进行此更改。

    【讨论】:

      【解决方案2】:

      您应该为新节点分配 malloc 内存:

      #include<stdio.h>
      #include <stdlib.h>
      
      struct node {
          int data;
          struct node *next
      };
      
      int main(void) {
          struct node *root, *list;
          int i;
          root = malloc(sizeof(struct node));
          list = root;
          root->next = NULL;
      
          list->data = 1;
          list->next = malloc(sizeof(struct node));
          list = list->next;
      
          list->data = 2;
          list->next = malloc(sizeof(struct node));
          list = list->next;
      
          list->data = 3;
          list->next = malloc(sizeof(struct node));
          list = list->next;
      
          list->data = 4;
          list->next = malloc(sizeof(struct node));
          list = list->next;
      
          list->data = 5;
          list->next = malloc(sizeof(struct node));
          list = list->next;
      
          list->next = NULL;
          while (root->next != NULL) {
              printf("%d\n", root->data);
              root = root->next;
          }
      }
      

      测试

      1
      2
      3
      4
      5
      

      【讨论】:

        【解决方案3】:

        当然,根节点的next 项始终是NULL,因为您没有为其分配任何其他值。像 root-&gt;next = another_node 这样的东西不见了。

        有一些很好的教程可以帮助你实现这个,例如

        1. learn-c.org
        2. cprogramming.com

        【讨论】:

          【解决方案4】:

          链接不同节点的方式存在问题。仔细看这段代码:

          list->data = 1;
          list->next = NULL;
          list = list->next;
          
          list = malloc(sizeof(*list));
          list->data = 2;
          list->next = NULL;
          

          您应该将新节点分配给前一个节点的下一个节点。但是当你做list = list-&gt;next。您的列表变量变为NULL。相反,您应该这样做:

          list->data = 1;
          list->next = NULL;
          
          list->next = (node *)malloc(sizeof(list));
          list = list->next;
          list->data = 3;
          list->next = NULL;
          
          
          list->next = (node *)malloc(sizeof(list));
          list = list->next;
          list->data = 4;
          list->next = NULL;
          

          【讨论】:

            【解决方案5】:

            当您获得指针的大小时,例如sizeof(list),然后你会得到 pointer 的大小,而不是它所指向的大小。你应该改用sizeof *list

            下一个问题是这样的:

            list = list->next;
            
            list = malloc(sizeof(list));
            

            第一行使list 指向list-&gt;next 所指向的位置,即NULL。下一行重新分配变量指向一些新分配的内存。您实际上没有将新节点链接到列表中。

            我建议改为:

            list = root;
            
            list->data = 1;
            list->next = malloc(sizeof *list);
            list = list->next;
            
            list->data = 2;
            // etc...
            

            【讨论】:

            • 感谢您了解并提出 sizeof(list) vs sizeof(*list)!
            猜你喜欢
            • 1970-01-01
            • 2020-07-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-09-16
            • 1970-01-01
            相关资源
            最近更新 更多