【问题标题】:Linked-List without malloc but with another approaches没有 malloc 但有另一种方法的链表
【发布时间】:2017-04-27 11:08:04
【问题描述】:

我有一个任务要求我使用链表来存储一些数据,但我只能使用<stdio.h>

我正在考虑使用数组,但在到达数组末尾的情况下无法扩展数组(我在大约 15 分钟前从这里读到这是不可能的:How can I change the size of an array in C?)。

然后我想也许我写了malloc函数?但这对我来说很麻烦,因为我是 C 新手。

另一个猜测是考虑通过分配给函数中的变量而不是返回来创建新节点。我在想,如果我在函数中定义一个变量,它会在每次调用错误的函数时分配一个足够大小的新内存。

现在,我不知道该怎么办,我应该坚持允许使用<stdlib.h> 吗?或者有没有办法或者我应该只使用带有链表的数组?

【问题讨论】:

  • malloc 不在stdio.h 内。您可以通过拥有struct 的数组并将数组索引用作链接来实现链接列表,如果没有链接,则使用-1。如果你想要一个动态的事件,你可以有另一个可用元素的链接列表。
  • 您可以使用固定大小的数组作为内存源还是需要处理不确定的大小?如果您可以使用固定大小的数组,则可以从中分配列表节点。
  • 如果你是初学者,你不需要编写自己的分配器(无论如何,它需要使用固定大小的数组来分配)。您确定需要在存储空间已满时对其进行扩展吗?
  • 你想用链表管理什么样的数据?
  • 您可以有一个固定大小的数组,其中的元素链接到一个“空闲”列表。当你想分配一个列表元素时,如果它是非空的,就从“空闲”列表中取出它。如果它为空,则打印错误并退出程序。除了你不能调用exit,因为你只能使用stdio.h,所以你必须从你的main函数返回。

标签: c arrays linked-list malloc


【解决方案1】:

由于您无法在堆上创建列表(malloc、calloc 等),因此您必须声明内存需求并在列表结构内部管理该内存。

我会帮你开始的。

#define LIST_MEM_POOL 1024
#define NODE_MEM_POOL 1024 

typedef struct {
    int item; /* Assuming you are storing integers in the linked list */
    struct Node *next;
} Node, *Pnode;

typedef struct {
    struct Node *head; /* Assuming singly linked list */
    int size;
} List, *Plist;

static List list_memory[LIST_MEM_POOL];
static Node node_memory[NODE_MEM_POOL];

static int used_lists = 0, free_lists = LIST_MEM_POOL;
static int used_nodes = 0, free_nodes = NODE_MEM_POOL;

Plist create_list(void) {
    Plist l = 0;
    if (used_lists < free_lists) {
        l = &list_memory[used_lists++];
        l->size = 0;
        l->head = 0;
    }
    return l;
}

用于创建列表的相同想法可以应用于创建节点。


在自行管理此内存方面,您需要担心一些问题:

  • 您将如何处理空闲内存?
  • 如果有人创建两个列表,释放第一个列表,然后 尝试创建新列表?
  • 当有人尝试创建列表但没有内存时会发生什么 可用吗?

【讨论】:

    【解决方案2】:

    开箱即用;)

    #include <stdio.h>
    
    #define N       0x20
    
    struct data_struct
    {
        char data_array[1];
        struct data_struct *next;
    };
    
    int main()
    {
        FILE * fp;
        unsigned int i;
        static struct data_struct head = {0};
        static struct data_struct tmp = {0};
    
        fp = fopen("file.dat", "w+");
    
        head.data_array[0] = 'A';
        head.next = (struct data_struct *)(ftell(fp) + sizeof(struct data_struct));
    
        fwrite(&head, 1, sizeof(struct data_struct), fp);
    
        for(i = 0; i < N; i++) {
            tmp.data_array[0] = 'B' + i;
            tmp.next = (struct data_struct *)(ftell(fp) + sizeof(struct data_struct));
            fwrite(&tmp, 1, sizeof(struct data_struct), fp);
        }
    
        fseek(fp, 0, SEEK_SET);
    
        fread(&head, 1, sizeof(struct data_struct), fp);
    
        for(i = 0; i < N; i++) {
            printf("data_array: %c\n", head.data_array[0]);
    
            fseek(fp, (unsigned int)head.next, SEEK_SET);
            fread(&head, 1, sizeof(struct data_struct), fp);
        }
    }
    

    【讨论】:

    • 好主意,只有&lt;stdio.h&gt;...并且可扩展。如果您添加一个setbuf() 具有固定但较大的缓冲区大小,您应该提高搜索功能期间的性能。
    • 感谢您的回答,因为我今天有一个测验,所以我不能足够照顾答案。我没有在 C 语言中体验过文件处理。我将在星期六再进行一次测验和期中考试,所以我需要推迟处理这项作业,如果我不能说服助手使用 ,我会尝试你的建议: )
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 2017-02-22
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 2023-01-22
    • 2011-10-15
    相关资源
    最近更新 更多