Вставка двусвязного списка в функцию и параметры конкретного списка

У меня есть следующий код, который является частью реализации двусвязного списка. Затем я должен использовать мою реализацию ADT для создания таблицы вида value (который является строкой), address (который имеет тип uint32_t) (поэтому таблица с 2 столбцами).

typedef struct {
    char *label; // is a string like "mov".
    uint32_t labelAddress; // the address of the label.
} individualEntry;

typedef void( *FreeList )( void* );

typedef struct listEntries {
    individualEntry newInstr;
    struct listEntries *prev;
    struct listEntries *next;
} listEntries;

listEntries *head;

/*
 * HELPER FUNCTIONS
 */

listEntries *createNewList() {
    listEntries *newListPtr = malloc(sizeof(listEntries));
    return newListPtr;
}

listEntries *createNewEntry( char *label, uint32_t address ) {
    listEntries *newEntry = (listEntries*) malloc(sizeof(listEntries));
    newEntry->prev = NULL;
    newEntry->next = NULL;
    newEntry->newInstr.label = label;
    newEntry->newInstr.labelAddress = address;
    return newEntry;
}

void insert( char *label, uint32_t address ) {
    listEntries *temp = head;
    listEntries *newEntry = createNewEntry(label, address);
    if ( head == NULL ) {
        head = newEntry;
        return;
    }
    while ( temp->next != NULL ) {
        temp = temp->next;
    }
    temp->next = newEntry;
    newEntry->prev = temp;
}

Мне нужно сначала создать эту таблицу, а затем добавить к ней записи.

Моя проблема заключается в реализации функции, которая вставляет в эту конкретную таблицу значения, которые будут добавлены. Нужна ли мне другая функция вставки, или мне нужно отредактировать ту, которая у меня есть?

Если мне нужна новая функция, которая принимает в качестве параметров: указатель на новую таблицу типа struct listEntries, строка и адрес записи, которую нужно добавить, нужно ли учитывать в параметрах предыдущую и следующую записи моего списка?

Я не уверен, как обрабатывать предыдущий и следующий указатели после вставки.

Может кто-нибудь опубликовать реализацию такой функции?

2 ответа

Решение

Так что это мой ответ на мой собственный вопрос (скомпилирован, протестирован, и он работает). Я использовал итераторы, спасибо за визуализацию выше, но мне нужно было больше советов, таких как слово итераторы.

void insert(struct list *listPtr, listIterator iter, int value) { 

struct listEntry *newEntry = list_alloc_elem(); // a helper that allocates memory for an individual entry; 
newEntry->value = value;
newEntry->prev = iter->prev;
newEntry->next = iter;
iter->prev->next = newEntry;
iter->prev = newEntry;
}

Единственное, что вам нужно, чтобы вставить элемент в (дважды) связанный список, это ссылочный узел, и где вы хотите вставить его до или после этого узла. Определенный лучший способ решить это - визуализировать это. Вы всегда должны быть осторожны, чтобы убедиться, что ссылки в обоих направлениях являются правильными, и вам, вероятно, было бы хорошо иметь некоторую самопроверку для этого на месте, поэтому каждый указанный узел указывает назад на тот же узел, в противном случае у вас есть проблема целостности.

А теперь для наглядности. Думайте об этом так (двойные линии представляют двойные ссылки):

A = B = C

Скажем, я хочу добавить элемент в этот список в конце, мне просто нужно сказать C, чтобы он указывал на этот элемент, например:

A = B = C - D

И укажите этот пункт обратно:

A = B = C = D

Теперь, если бы я хотел, чтобы переместить D на другую позицию, скажем, на второй, я могу позволить опорный узел "A", чтобы указать на "D":

A - B = C = D
 \_________/

Пусть D укажет на A

A - B = C - D
 \`========'/

У C больше нет указания на D:

A - B = C   D
 \`========'/

Пусть D указывают на B:

      ______
     /      \
A - B = C   D
 \`========'/

Пусть B укажет на D:

      .=====
     //     \\
A   B = C   D
 \`========'/

Как вы теперь видите, B больше не указывает на a, и визуальная перестановка решает эту проблему:

   C = B ===.
           \\
A           D
 \`========'/

равна:

A = D = B = C

Если вы понимаете это, вы можете выполнить любую операцию в двусвязном списке. и спасибо за возможность заняться искусством.

Подводя итог: у вас на самом деле нет "списка". У вас есть только узлы, указывающие на другой узел, который указывает назад, или на ничто (NULL).

Другие вопросы по тегам