当前位置: 首页 > 知识库问答 >
问题:

单点链接列表:newNode函数不指向下一个节点

邹野
2023-03-14

我目前正在尝试使用C语言中的单链表。我编写了一个newNode函数来创建一个节点,并编写了一个printNodes函数来打印所有节点-看起来如下:

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

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

void printNodes(struct Node *current_node)
{
  while(current_node != NULL)
  {
    printf("Node is: %d\n", current_node->data);
    current_node = current_node->next;
  }
}

int main()
{
  int number_1 = 2;
  int number_2 = 3;
  int number_3 = 4;

  struct Node *head;
  struct Node *second;
  struct Node *third;

  head = (struct Node*)malloc(sizeof(struct Node));  
  second = (struct Node*)malloc(sizeof(struct Node)); 
  third = (struct Node*)malloc(sizeof(struct Node));

  head->data = number_1;      
  head->next = second; 

  second->data = number_2;      
  second->next = third; 

  third->data = number_3;     
  third->next = NULL; 

  printNodes(head);

}

输出正确:

Node is: 2
Node is: 3 
Node is: 4

现在我想写一个函数newNode,用于创建一个新的节点,我把我的代码改成这样:

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

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

struct Node *newNode(int number_x, struct Node *nextnode)
{
    struct Node *tmp_node;

    tmp_node = malloc(sizeof(struct Node));
    tmp_node->data = malloc(sizeof(struct Node));
    tmp_node->data = number_x;
    tmp_node->next = nextnode;

    return tmp_node;
}   

void printNodes(struct Node *current_node)
{
    while(current_node != NULL)
    {
        printf("Node is: %d\n", current_node->data);
        current_node = current_node->next;
    }
}

int main()
{
    int number_1 = 2;
    int number_2 = 3;
    int number_3 = 4;

    struct Node *head;
    struct Node *second;
    struct Node *third;

    head = newNode(number_1, second);
    second = newNode(number_2, third);
    third = newNode(number_3, NULL);

    printNodes(head);

}

编译后,我首先得到这个警告消息:

test.c:16:20: warning: incompatible pointer to integer conversion 
assigning to 'int' from 'void *' [-Wint-conversion]
tmp_node->data = malloc(sizeof(struct Node));
               ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~

输出如下所示:

Node is: 2

它只显示节点头部,我猜下一步指向(例如头部)有问题-

谢谢


共有3个答案

阴福
2023-03-14

感谢@WhozCraig的澄清。

正如他所提到的,second节点不知道他的输入是什么。要分解它,如果您编写如下内容,也会发生同样的情况:intnum;printf(“%d”,num)

程序不知道输入是什么,因为还没有初始化输入。

我的程序也发生了同样的事情,没有初始化节点,因此程序不知道下一个节点在哪里。但是如果我向后写程序,程序现在确实理解了值是什么,并且可以使用它:

    //use it backwards
    third = newNode(number_3, NULL);
    second = newNode(number_2, third);
    head = newNode(number_1, second);

现在,输出正确:

Node is: 2
Node is: 3
Node is: 4

谢谢你的帮助,干杯。

胡昊
2023-03-14

首先,您看到的警告(应视为错误,仅供参考)与您的整体问题无关,但仍然很重要。它既不合适,又会泄漏内存,而且有测试意大利面条的模糊外观。如果你从来没有这样做过,一个老式的厨房技术,看看意大利面是否“做”了,就是从锅里拿出一条线,直接扔到墙上,看看它是否粘在一起。这个看似无关的代码行看起来就是这样;就像你往墙上扔东西看它是否卡住了:

这:

tmp_node->data = malloc(sizeof(struct Node)); // DELETE THIS

甚至不应该出现在代码中;下一行是应该做的,即:

tmp_node->data = number_x; // KEEP THIS

接线链接列表

虽然之前的抨击令人担忧,但这并不是传递你不令人羡慕的立场的原因,即没有正确地连接你的列表。这本身就是一个问题。考虑以下几点:

struct Node *head;      // indeterminate
struct Node *second;    // indeterminate
struct Node *third;     // indeterminate

在前两个newNode调用中,您将不确定的指针值传递给最终将是新分配的节点下一个指针。这意义重大。我颠倒了构建顺序,你可以得到你想要的行为。

third = newNode(number_3, NULL);    // third is set, next points to NULL
second = newNode(number_2, third);  // second it set, next points to third
head = newNode(number_1, second);   // head is set, next points to second

显然,必须这样做并不理想,但要了解事物是如何连接的,这是一种方法。另一种是直接分配给下一个成员。例如:

head = newNode(number_1, NULL); 
head->next = newNode(number_2, NULL);
head->next->next = newNode(number_3, NULL);

这也行得通,但同样不理想。您真的想这样做来构建一个包含100个节点的链接列表吗?

正向链接链表

有一种非常简洁的方法可以构建升序链表,而无需执行上述操作。它被称为前向链接,并利用指向指针的指针,该指针最初指向头指针本身(最初为空):

struct Node *head = NULL;
struct Node **pp = &head; // points to a pointer, initially the head pointer

有了以上这些,我们可以把你想要的元素串成一个列表。一百块?没问题:

for (int i=1; i<=100; ++i)
{
    // allocate a new node, storing the address at whatever pointer
    // is being addressed by the pointer-to-pointer pp. Initially it
    // will be the `head` pointer variable.

    *pp = malloc(sizeof **pp);
    (*pp)->data = i;

    // move pp to point to the next pointer of the node we just added
    pp = &(*pp)->next;
}
*pp = NULL; // terminate the list


printNodes(head);

这只是构建链接列表的一种方法。还有很多其他的方法(例如,在学校学习递归时,递归的方法并不少见)。但它可能是最简单的,几乎肯定是最快的。

无论如何,这比我预期的要长,但我希望这能有所帮助。

段志
2023-03-14

这儿呢

tmp_node->data = malloc(sizeof(struct Node)); /* remove this statement */

datastruct Node的成员

tmp_node = malloc(sizeof(struct Node)); /* this is enough */

也在这里

head = newNode(number_1, second);

什么是秒?它应该用NULLlike初始化

struct Node *second = NULL;

然后仅在newNode()函数tmp\u节点中-

tmp_node->next = nextnode; /* now nextnode contains NULL, that's correct */

或者你可以像下面这样做

head = newNode(number_1, NULL);
second = newNode(number_2, head);
third = newNode(number_3, second);

然后在调用printNodes()时,传递第三个,而不是。例如

printNodes(third);

示例代码:

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

struct Node *newNode(int number_x, struct Node *nextnode) {
    struct Node *tmp_node;
    tmp_node = malloc(sizeof(struct Node));
    tmp_node->data = number_x;
    tmp_node->next = nextnode;
    return tmp_node;
}

void printNodes(struct Node *current_node) {
    while(current_node != NULL) {
        printf("Node is: %d\n", current_node->data);
        current_node = current_node->next;
    }
}

int main(void) {
    int number_1 = 2;
    int number_2 = 3;
    int number_3 = 4;

    struct Node *head = NULL;
    struct Node *second = NULL;
    struct Node *third = NULL;

    head = newNode(number_1, NULL);
    second = newNode(number_2, head);
    third = newNode(number_3, second);
    printNodes(third);
        return 0;
}

 类似资料:
  • 我正在制作一个方法,将一个节点添加到名为“publicvoidadd(int-index,T-value)”的列表中。 此方法将把一个值放入索引中,然后将有指向列表中下一个和上一个元素的指针。我把指向前面节点的指针搞砸了,我一直坐在那里进行实验,但没有让它工作。 示例:我们有一个包含整数值[2,4,6]实例变量的列表:Node head、tail;整数金额,变动; 内部类的实例变量为:T值;节点p

  • 在Java中,从单链接列表中删除节点时遇到问题。我有一个列表,其中包含整数的数据,我需要删除所有节点,它们的值可以被四除。我还需要移动head和tail指针,以防head或tail元素被删除。我为此编写了一个方法,大多数时候,它的工作方式和我需要的一样,但有时它会抛出NullPointerException。我怎样才能修好它?这是我的密码:

  • 给定一个单链表和中间节点从一开始的编号,我试图通过将最后一个节点指向中间节点来创建一个循环单链表。我写了以下代码: 然而,Linkedlist的最后一个节点仍然指向null而不是中间节点。我明白我哪里出错了,我找不到它。请帮忙。

  • 问题内容: 我正在练习使用链表节点,遇到了一个我不知道如何回答的问题。如何删除链接列表中的最后一个节点。下面的代码适用于所有条目的最后一个节点。最后一个不会被删除。 节点类别 主要 问题答案: 我想您的最后一个元素失败了。最后一个元素将没有元素。因此,不会将最后一个元素与传递的字符串进行比较。您应该使用调试器进行跟踪。

  • 以下代码删除双链接列表中的第一个节点。 如果列表只包含1个元素,我们将last的引用设置为null。我的问题是,我们为什么不将first的引用设置为null?这会有什么不同吗?