繁体   English   中英

使用指向结构的指针在C中创建链接列表和内存分配

[英]Using pointer to a struct to create linked list and Memory allocation in C

我想一个概念问题。 当我需要创建一个链表时,只是给了我一个指向结构的指针(该结构包含一些数据类型和指针“ next”)。 如何确保创建其他链接,而不仅仅是根节点? 我没有使用malloc,否则这将是更明显的答案。 该列表本身充当malloc。

提前致谢!

澄清:

将存在一维数组,它将充当固定大小的内存块。 然后,链表将通过删除节点并将其放入数组中进行“分配”,或者通过将其从数组中删除以添加回列表中来“释放”数据。

(由某种数据类型和指针定义的结构)该结构称为节点

node array[10];  //this acts as memory
node* linked_list;  //this gives or removes data to memory (array)

这类似于我们使用FORTRAN 77(早在白垩纪时期)在Data Structures类中进行操作的方式; 我们分配了一个固定大小的数组,并将其用作我们的内存池。

基本上,您必须维护一个“免费”列表。 这些是可以使用的节点。 首次启动时,将初始化数组中的每个元素以显式指向下一个元素:

struct node {T data; struct node *next; } pool[N]; // for some type T
...
for (i = 0; i < N-1; i++)
  pool[i].next = &pool[i+1];
pool[i].next = NULL;

您的空闲列表最初指向池中的第一个元素:

struct node *free = &pool[0];

当您分配一个节点,检索元素free点,更新free指向下一个可用的元素列表(如果存在的话),然后初始化元素作为必要的:

if (free) // is there a free node available
{
  struct node *newNode = free;
  free = free->next;
  newNode->data = ...;
  newNode->next = NULL;
  ...
}

完成节点后,将其添加回free列表的头部:

node->next = free;
free = node;

自然地,真正的代码会比这更好的组织,但是这应该足以使您了解要做什么。

我不确定这是否适用于您的特定问题,但是我想指出一些有关在不使用malloc情况下创建链接列表的信息。

动态或静态地分配链表的节点并不重要。 重要的是每个节点实际上都存在并且指针有效。

例如,我们可以从数组构建链接列表。

#include <stdio.h>

typedef struct node_t {
    int value;
    struct node_t *next;
} node;

int main() {

    int i;
    node linked_list[10];

    // build the linked list
    for ( i = 0; i < 10; i++ ) {
        linked_list[i].value = i * i;
        linked_list[i].next = ( i < 9 ) ? &linked_list[i+1] : 0;
    }

    // now traverse it
    node *head = &linked_list[0];
    while ( head ) {
        printf( "%d\n", head->value );
        head = head->next;
    }
}

编辑 :为了使用数组作为从中“分配”或“释放”链表节点的位置,可以使用标志来扩充节点struct ,以指示是否正在使用该节点。

typedef struct node_t {
    char in_use;
    int value;
    struct node_t *next;
} node;

EDIT2 :让我们最后一次尝试。 下面是从数组“分配”一个节点的函数(如果没有可用的节点,则返回NULL )。 假设linked_list是全局的。

node *get_node() {
    int i;
    for ( i = 0; i < 10; i++ )
        if ( !linked_list[i].in_use ) {
            linked_list[i].in_use = true;
            return &linked_list[i];
        }
    return 0;
}

EDIT3 :如果将数组用作内存池,那么John Bode的答案就是走。

有几种可能的方案:

  • 链表使用的是malloc。 然后,链表负责节点的分配和取消分配。 这是标准实现。

  • 链表使用的是静态分配的内存块,即固定大小的静态数组。 这样的链表更加复杂,因为您必须跟踪数组中包含数据的哪些部分。 您还需要跟踪链接列表的大小。

  • 链接列表是“带有索引查找表的节点数组”。 然后,它不分配任何数据,而是每个节点包含的数组索引。 链接列表将需要跟踪列表大小。

  • 链表未执行任何分配。 分配由调用方完成(静态或动态)。 在这种情况下,链接列表仅跟踪下一个指针,不分配任何内容。 该版本的对象设计不佳,因为它破坏了数据的私有封装。

更改操作后进行编辑:看来您正在使用上面的版本3。 Google用于“使用数组的链接列表”或类似内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM