Как удалить узел в отдельно списке ссылок только с одним указателем, указывающим на узел, который будет удален?
[Запустите и закончитесь, указатели не известны, доступной информацией является указатель на узел, который должен быть удален]
Вы можете удалить узел, не получив предыдущий, имитируя следующий узел и удалив вместо него:
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;
}
}
Как видите, вам придется иметь дело специально с последним элементом. Я использую специальный узел в качестве узла-докладчика, чтобы пометить окончание, в котором контент
и следующий
будет 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*
Затем измените следующие
пункты:
A / To be deleted
next ---> C /----------------
next ---| C |
next ---> *sentinel*
Фактически освобождается следующий элемент, попадая в финальный случай:
A / To be deleted
next ---> C
next ---> *sentinel*
Невозможно.
Есть взломы, чтобы имитировать удаление.
Но ни один из них не удалит узел, на который указывает указатель.
Популярное решение удаления следующего за узла и копирования его содержимого в фактический удаляемый узел имеет побочные эффекты, если в списке есть внешние указатели , указывающие на узлы, и в этом случае внешний указатель, указывающий на следующий узел, становится висячим.
Обсуждение SO можно найти здесь .
.Единственная разумная и безопасная опция при таких ограничениях - это пометить удаленный узел без его фактической разблокировки, отложив это на более позднее время.
.