Puede eliminar un nodo sin obtener el nodo anterior, al tener que imitan el siguiente nodo y la supresión de que uno en su lugar:
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;
}
}
Como puede ver, tendrá que ocuparse especialmente del último elemento. Estoy usando un nodo especial como nodo centinela para marcar la terminación que tiene content
y next
sea NULL
.
ACTUALIZACIÓN: las líneas Node *next = n->next; n->next = n->next->next
básicamente baraja el contenido del nodo, y libera el nodo: La imagen que se obtiene una referencia al nodo B para borrar en:
A /To be deleted
next ---> B
next ---> C
next ---> *sentinel*
El primer paso es n->content = n->next->content
: copiar el contenido de la siguiente nodo al nodo de ser "eliminado":
A /To be deleted
next ---> C
next ---> C
next ---> *sentinel*
Entonces, modificar los next
puntos:
A /To be deleted
next ---> C /----------------
next ---| C |
next ---> *sentinel*
El realmente libre el siguiente elemento, llegando al final del caso:
A /To be deleted
next ---> C
next ---> *sentinel*
Node * siguiente = n-> siguiente; n-> siguiente = n-> siguiente-> siguiente; ¿Puedes por favor elaborar esto más? – user215968
Si la lista enlazada es lo suficientemente larga, ¿será el cambio de contenido una solución viable? – user215968
@unknown, sí, sería una solución factible. Este enfoque puede complicar el aliasing (otro código contiene una referencia a los nodos afectados y tal); pero lo tendrás de todos modos. – notnoop