C中的链表数组:初始化和插入?

Posted

技术标签:

【中文标题】C中的链表数组:初始化和插入?【英文标题】:Array of Linked Lists in C: initializing and inserting? 【发布时间】:2018-03-01 10:11:30 【问题描述】:

我需要创建一个链表数组(如图),这就是我目前所做的:

typedef struct Node 
    int data;
    struct Node *next;
 Node;

int main(void) 
    Node* link[5];
    for(int q = 0; q < 5; q++) 
        link[q] = malloc(sizeof(struct Node));
        link[q] = NULL;
    

自从我在 C 语言中使用链表已经有一段时间了,所以我忘记了很多语法,而且我很难想象在编写链表时到底发生了什么。如果我没记错的话,当我在代码中调用 malloc 时,我正在创建一个没有任何内容的节点?

我想将它初始化为指向 NULL。我这样做了

link[q] = NULL;

我说这就是记忆中的样子对吗?

|1| -> 空

|2| -> 空

|3| -> 空


我的下一个问题是将数据插入到链表中。

(参考图片):如果我想在数组的第三个索引中插入另一个元素([3]-> d -> NULL)

这是正确的吗?

Node* newNode = link[3];
newNode->data = 1;
link[3] = newNode;

感谢您的帮助!

【问题讨论】:

插入无效。再次出现内存泄漏。看我的回答。 谢谢!将尽快编辑:) 请问为什么会出现内存泄漏? 调用 malloc 而不是 newNode = link[3];正如它所写的那样,你必须写 newNode->next = link[3]; 【参考方案1】:

这个循环

Node* link[5];
for(int q = 0; q < 5; q++) 
    link[q] = malloc(sizeof(struct Node));
    link[q] = NULL;

导致内存泄漏,因为首先分配了内存,然后指针被 NULL 覆盖。这样分配的内存地址就丢失了。

你可以写

Node* link[5] =  0 ;

这是一个演示程序,展示了如何将节点添加到列表数组的元素中。 int 类型的数据成员 data 的 Insetad 我正在使用 char 类型的数据成员 data 来获取可见性。

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

typedef struct Node 

    char data;
    struct Node *next;
 Node;


int push_front( Node **head, char data )

    Node *new_node = malloc( sizeof( Node ) );
    int success = new_node != NULL;

    if ( success )
    
        new_node->data = data;
        new_node->next = *head;
        *head = new_node;
    

    return success;


void output( Node **head )

    for( Node *current =*head; current != NULL; current = current->next )
    
        printf( "%c ", current->data );
    
    printf( "%s", "NULL" );


void display( Node **set, size_t n )

    for ( size_t i = 0; i < n; i++ )
    
        output( set++ );
        putchar( '\n' );
    


#define N   5

int main(void) 

    Node * link[N] =  0 ;

    push_front( &link[0], 'b' );
    push_front( &link[0], 'a' );
    push_front( &link[1], 'c' );
    push_front( &link[2], 'd' );

    display( link, sizeof( link ) / sizeof( *link ) );

    return 0;

程序输出是

a b NULL
c NULL
d NULL
NULL
NULL

【讨论】:

在你的函数push_front中,你为什么要这样做? [int成功=新节点!=空; ] 是否会有 new_node 指向 NULL 的情况(在为它分配空间之后?尤其是函数的目的是为它收集数据?)。为什么我们返回成功的价值?是否需要返回值?将函数声明为“void”不一样吗? @Katrina 函数 malloc 可能会失败。您需要一种方法来确定节点是否已成功添加到列表中。 再次感谢您! :) 在他的例子中,他知道link的大小是5。如果你不知道数组的大小,你会怎么做? 我们怎样才能给每个节点一个结构体?【参考方案2】:

据我了解你的程序,下面的语句是不必要的:

link[q] = malloc(sizeof(struct Node));

由于需要从 NULL 指针开始,所以 link[q] = NULL;刚刚好。

要在列表中插入项目,您应该为每个项目分配内存,所以它应该变成这样:

Node* newNode = malloc(sizeof(struct Node));
newNode->data = 1;
newNode->next = link[3];
link[3] = newNode;

它应该可以工作,虽然我没有测试它。

【讨论】:

谢谢!我提取了您的插入代码,我认为在为 newNode 分配空间之后,您必须使用 newNode = link[3] 将其指向链接 [3] 所指向的内容 好吧,如果将分配内存的指针保存在 newNode 中,那么您也需要将指针分配给 link[3],但反之则不然。所以应该是 link[3] = newNode. 我的错误。我实际上指的是 newNode->next = link[3],起初我认为是 newNode = link[3]。还是谢谢你:)【参考方案3】:

您已经有一个由 5 个指向节点的指针组成的数组,即link。您只需执行以下操作即可将它们设置为不指向任何内容:

for (size_t i = 0; i < sizeof link / sizeof *link; ++i)
 link[i] = NULL;

在这里你不应该分配任何新的存储,因为你不需要实际的节点,你只需要指向节点的指针并且你已经有了它们。

您的代码首先分配,然后立即用NULL 覆盖malloc() 返回的指针,实际上永远失去了该内存。不好。

当你想真正创建一个节点时,你需要分配它并将它链接到正确的列表中。

【讨论】:

好点!感谢您的洞察力。这意味着我要插入的代码应该更像... Node *newNode = malloc(sizeof(struct Node)) ?【参考方案4】:

首先,如果您不确定是否看到某些内容,最好的检查方法是打印出来。

其次,你的代码有错误——

    link[q] = malloc(sizeof(struct Node));
    link[q] = NULL;

在这里,您创建了一个大小为 struct Node 的新指针 void*,然后当您将 NULL 保存在变量 Link[i] 中时,您会失去他,您有 2 个选项:

    分配链接,然后用defualt fields初始化它,例如-data =-1 在初始化之前不要分配NULL并将其放入everty节点中

我的建议,选择 2,并且仅当您需要添加新节点分配时。

【讨论】:

以上是关于C中的链表数组:初始化和插入?的主要内容,如果未能解决你的问题,请参考以下文章

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

求C语言 数据结构中的链表创建,插入和删除代码

第二章内容小结

Java 数组

vector运算起来是否很慢啊?

初始化链表节点