【问题标题】:How should I implement capacity for C Dymanic Linked List?我应该如何实现 C 动态链接列表的容量?
【发布时间】:2010-10-17 08:07:14
【问题描述】:

我知道当您将它用作 OOP 语言中的 ADT 时,它很容易实现。

但是对于像 C 这样的结构化语言应该怎么做呢?

我应该使用全局变量吗?

我应该在每个节点中保留一个额外的变量吗?

还是什么?

我已经实现了我的动态堆栈,例如this。

如您所见,没有容量检查。

【问题讨论】:

  • 在链表实现中,我假设您将一次添加和删除一个节点。您担心容量的唯一一次是您是否在 add(即 malloc)上用完了 ram。这是您担心的问题还是您正在尝试优化某些内容?

标签: c stack-overflow capacity


【解决方案1】:

如果您想对链表实施容量限制,最好的方法是设置每个列表的限制。以下结构将允许:

// List structure: first/last pointers plus remaining capacity.
typedef struct {
    tNode *first;
    tNode *last;
    size_t freeCount;
} tList;

// Node structure: value pointer and next.
typedef struct sNode {
    void *val;
    struct sNode *next;
} tNode;

然后你初始化每个列表的限制:

// Creates an empty list.
tList *makeList (size_t limit) {
    tList *list = malloc (sizeof (tList));
    if (list == NULL)
        return NULL;
    list->freeCount = limit;
    list->first = list->last = NULL;
}

// Destroys a list after clearing it if necessary.
void destroyList (tList list) {
    void *val = getNode (list);
    while (val != NULL) {
        free (val);
        val = getNode (list);
    }
    free (list);
}

之后,如果freeCount为零,则添加节点将失败,否则将添加节点并减少freeCount。删除一个节点会增加freeCount,类似于:

// Puts an item on to the list end.
int putNode (tList *list, void *val, size_t sz) {
    // No more capacity.
    if (list->freeCount == 0) return -1;

    // Try to make node, returning error if no memory.
    tNode *node = malloc (sizeof (tNode));
    if (node == NULL) return -1;

    // Try to duplicate payload, clean up and return if no memory.
    node->val = malloc (sz);
    if (node->val == NULL) {
        free (node);
        return -1;
    }

    // Initialise node.
    memcpy (node->val, val, sz)
    node->next = NULL;

    // Adjust remaining capacity and insert into list.
    list->freeCount--;
    if (list->first == NULL) {
        list->first = list->last = node;
    } else {
        list->last->next = node;
        list->last = node;
    }

    return 0;
}

 

// Gets an item from the list.
void *getNode (tList *list) {
    // If empty, just return NULL.
    if (list->first == NULL)
        return NULL;

    // Get first node and remove it from list.
    tNode node = list->first;
    list->first = list->first->next;

    // Get the payload and free the node.
    void *val = node->val;
    free (node);

    // Adjust remianing capacity and return payload.
    list->freeCount++;
    return val;
}

注意所有正常的错误情况(没有内存、列表为空等等)以及当您已经达到满容量时尝试添加节点的额外限制(当freeCount 为零时)。

【讨论】:

    【解决方案2】:

    链接/动态堆栈通过在其顶部添加一个新的动态分配节点来增长。现在内存永远不会是无限的,在动态增长的某一时刻,您将耗尽内存,您将无法创建新节点。这可以被视为堆栈溢出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-16
      • 2011-01-06
      • 2021-02-25
      • 1970-01-01
      • 2011-11-27
      • 1970-01-01
      • 2022-10-13
      相关资源
      最近更新 更多