Вы можете удалить узел без получения предыдущего узла, имея его имитировать следующий узел и удалить, что один вместо этого:
void delete(Node *n) {
if (!is_sentinel(n->next)) {
n->content = n->next->content;
Node *next = n->next;
n->next = n->next->next;
free(next);
} else {
n->content = NULL;
free(n->next);
n->next = NULL;
}
}
Как вы можете видеть, вам нужно будет иметь дело специально для последнего элемента. Я использую специальный узел в качестве сторожевого узла для отметки окончания, который имеет content
и next
be NULL
.
UPDATE: линии Node *next = n->next; n->next = n->next->next
в основном перемешивает содержимое узла и освобождает узел: Изображение, которое вы получаете ссылку на узел B должен быть удален в:
A /To be deleted
next ---> B
next ---> C
next ---> *sentinel*
Первый шаг n->content = n->next->content
: скопировать содержимое следующего узла к узлу, чтобы быть "удален":
A /To be deleted
next ---> C
next ---> C
next ---> *sentinel*
Затем измените next
точки:
A /To be deleted
next ---> C /----------------
next ---| C |
next ---> *sentinel*
Реально свободный следующий элемент, попадая в конечном случае:
A /To be deleted
next ---> C
next ---> *sentinel*
Узел * next = n-> next; n-> next = n-> next-> next; не могли бы вы рассказать об этом подробнее? – user215968
Если связанный список достаточно длинный, то смещение содержимого будет возможным решением? – user215968
@ неизвестно, да, это было бы приемлемым решением. Такой подход может усложнить сглаживание (в другом коде содержится ссылка на затронутые узлы и т. Д.); но это все равно. – notnoop