En esta entrevista de Slashdot, se cita a Linus Torvalds diciendo:
He visto a demasiadas personas que eliminan una entrada de la lista enlazada individualmente haciendo un seguimiento de la entrada "anterior", y luego eliminan la entrada, haciendo algo como
if (anterior) anterior-
> siguiente = entrada-> siguiente;
else
list_head = entry-> next;y cada vez que veo un código así, solo digo "Esta persona no entiende los punteros". Y lamentablemente es bastante común.
Las personas que entienden los punteros simplemente usan un "puntero al puntero de entrada" e inicializan eso con la dirección de list_head. Y luego, a medida que atraviesan la lista, pueden eliminar la entrada sin usar ninguna condición, simplemente haciendo un "* pp = entrada-> siguiente".
Como desarrollador de PHP, no he tocado punteros desde Introducción a C en la universidad hace una década. Sin embargo, siento que este es un tipo de situación con la que al menos debería estar familiarizado. ¿De qué está hablando Linus? Para ser honesto, si me pidieran implementar una lista vinculada y eliminar un elemento, la forma "incorrecta" anterior es la forma en que lo haría. ¿Qué necesito saber para codificar como Linus dice mejor?
Estoy preguntando aquí en lugar de sobre Stack Overflow, ya que en realidad no tengo problemas con esto en el código de producción.
prev
, en lugar de almacenar el nodo completo, puede almacenar la ubicación deprev.next
, ya que eso es lo único que le interesa. Un puntero a un puntero. Y si haces eso, evitas lo tontoif
, ya que ahora no tienes el extraño caso delist_head
ser un puntero desde fuera de un nodo. El puntero al encabezado de la lista es semánticamente igual que el puntero al siguiente nodo.