Функции со связным списком, где хранятся указатели
нужно реализовать набор функций для работы со связным списком, в котором всегда хранятся указатели. Список должен быть двусвязный со вспомогательным узлом. В узлах списка требуется хранить указатели на следующий или предыдущей узлы (уже не индексы, как можно было в предыдущих задачах). Каждый узел списка должен быть размещён в динамической памяти, выделенной с помощью malloc. Нужно реализовать следующие функции:
typedef struct Node_s {
struct Node_s * prev , * next ;
void * value ;
} Node ;
//List –- вспомогательный узел, являющийся головой списка
typedef Node List ;
//инициализирует поля структуры *list значениями для пустого списка
void initList ( List * list );
//создаёт новый узел со значением ptr и вставляет его после узла node
//возвращает указатель на созданный узел
Node * addAfter ( Node * node , void * ptr );
//создаёт новый узел со значением ptr и вставляет его перед узлом node
//возвращает указатель на созданный узел
Node * addBefore ( Node * node , void * ptr );
//удаляет заданный узел, возвращая значение, которое в нём лежало
void * erase ( Node * node );
Эти функции должны выделять/удалять память для узлов списка Node, но не для значений: вызывающий полностью контролирует то, куда указывают значения и как для них используется память. входные данные: В первой строке файла записано одно целое число ? — количество тестов в файле. Далее в файле идут тесты (? штук) подряд, один за другим. Первая строка теста начинается с целого числа ? — количество операций, которые нужно выполнить (0 <= ? <= 10^5)полагается, что в начале теста список пустой.Затем идут ? строк, которые описывают операции над списком. В каждой строке сначала записан тип операции: 1 — добавление спереди, -1 — добавление сзади, 0 — удаление. Затем указан индекс узла. Если описывается операция вставки, то в конце также задано целочисленное значение нового узла. Узлам присваиваются индексы в порядке их создания. Самый первый созданный узел имеет индекс 0, следующая операция создания имеет индекс 1, и так далее. Индекс узла никогда не переиспользуется, даже после того, как узел удаляют из списка. Все значения узлов лежат в диапазоне от 0 до 10^6 включительно. Сумма ? по всем тестах не превышает 10^5. **выходные данные:**Для каждого теста нужно вывести значения всех узлов списка после выполнения операций (в порядке их следования в списке), и строку "===" в конце. подскажите пожалуйста, что не так в моем коде, что можно подкорректировать или вставить:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct Node_s {
struct Node_s *prev, *next;
void *value;
} Node;
typedef Node List;
Node *first, *last;
Node *addAfter(Node *node, void *ptr) {
Node *nn = malloc(sizeof(Node));
nn->value = ptr;
if (node == 0) {
nn->next = first;
nn->prev = 0;
if (first)
first->prev = nn;
first = nn;
}
else {
//(тут наверняка ещё баг)
nn->prev = node;
nn->next = node->next;
node->next = nn;
}
return nn;
}
Node *addBefore(Node *node, void *ptr) {
Node *nn = malloc(sizeof(Node));
nn->value = ptr;
nn->prev = first;
nn->next = 0;
first->next = nn;
return nn;
}
void *erase(Node *node) {
if (node->next)
node->next->prev = node->prev;
if (node->prev)
node->prev->next = node->next;
node->prev = node->next = (Node*)0xFFFFFFFF;
return node->value;
}
Node *idToNodeXXX[100010] = {0};
Node* *idToNode = idToNodeXXX + 1; //указывает на 1-ый элемент
int idCnt;
//теперь idToNode[id] --- как бы массив от -1 до 100009
//отладочный вывод
void dp() {
//печатаем ВСЕ узлы (даже удалённые) в том виде, в котором нам удобнее проверять правильность
printf("F:%p L:%p\n", first, last);
for (int id = 0; id < idCnt; id++) {
Node *node = idToNode[id];
printf("%p:: V:%d | %p %p\n", node, *(int*)node->value, node->prev, node->next);
}
printf("----------\n");
fflush(stdout);
}
int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int tests;
scanf("%d", &tests);
dp();
for (int tn = 0; tn < tests; tn++) {
int q;
scanf("%d", &q);
for (int i = 0; i < q; i++) {
int type, id;
scanf("%d%d", &type, &id);
if (type == 1) {
//случай id == -1 работает нормально
Node *node = idToNode[id];
int *valueBuff = malloc(sizeof(int));
scanf("%d", valueBuff);
Node *nn = addAfter(node, valueBuff);
idToNode[idCnt++] = nn;
}
if (type == -1) {
Node *node = idToNode[id];
int *valueBuff = malloc(sizeof(int));
scanf("%d", valueBuff);
Node *nn = addBefore(node, valueBuff);
idToNode[idCnt++] = nn;
}
if (type == 0) {
Node *node = idToNode[id];
void *ptr = erase(node);
}
dp();
}
//печатаем от first до нулевого указателя
for (Node *ptr = first; ptr; ptr = ptr->next)
printf("%d\n", *(int*)ptr->value);
printf("===\n");
}
return 0;
}