Как мне реализовать емкость для C Dymanic Linked List? - PullRequest
2 голосов
/ 17 октября 2010

Я знаю, что это очень легко реализовать, когда вы используете его как ADT на языках ООП.

Но что делать в случае структурированного языка, такого как C?

Должен ли яиспользовать глобальную переменную?

Должен ли я хранить дополнительную переменную в каждом узле?

Или что?

Я реализовал свой динамический стек, как this ,

Как видите, проверка емкости не производится.

Ответы [ 2 ]

3 голосов
/ 17 октября 2010

Если вы хотите установить ограничение емкости для связанного списка, лучшим способом будет ограничение для каждого списка. Следующие структуры позволят это:

// 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 - ноль).

1 голос
/ 17 октября 2010

Связанные / динамические стеки растут, добавляя новый динамически размещенный узел в его верхнюю часть. Теперь память никогда не бывает неограниченной, в какой-то момент в динамическом росте вам не хватит памяти, и вы не сможете создать новый узел. Это можно рассматривать как переполнение стека.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...