¿Por qué la lista doblemente enlazada en sys / queue.h mantiene la dirección del siguiente elemento anterior?

Estoy estudiando sys/queue.h de FreeBSD y tengo una pregunta:

En sys/queue.h , LIST_ENTRY se define de la siguiente manera:

 #define LIST_ENTRY(type) \ struct { \ struct type *le_next; /* next element */ \ struct type **le_prev; /* address of previous next element */ \ } 

¿Por qué mantiene la dirección del siguiente elemento anterior ( struct type **le_prev ) en lugar de simplemente elment anterior como struct type *le_prev ?

Si hubiera leído el archivo queue.h desde el principio, es posible que tenga el siguiente comentario:

  * A list is headed by a single forward pointer (or an array of forward * pointers for a hash table header). The elements are doubly linked * so that an arbitrary element can be removed without a need to * traverse the list. New elements can be added to the list before * or after an existing element or at the head of the list. A list * may only be traversed in the forward direction. 

tan lista, que proporciona O (1) inserción y eliminación, pero solo avance transversal. Para lograr esto, solo necesita la referencia al siguiente puntero, que es exactamente lo que se implementa.

Déjame intentar explicar. En realidad, el **le_prev* permite una lista a la lista definida por sys / queue.h para insert_before que la lista de reenvío no puede. Comparado con insert_before , el insert_after puede implementarse bien en la lista o en la lista hacia adelante. Así que la lista es más funcional.

 insert_before(entry* list_elem, entry* elem, type val) { elem->next = list_elem; *(list->prev) = elem; elem->prev = *(list->prev); list_elem->prev = elem->next; } insert_after(entry* list_elem, entry* elem, type val) { if( ((elem)->next= (list_elem)->next) != NULL ) { (elem_list)->next->prev = &(elem)->next; } (list_elem)->next = elem; elem->prev = &(list_elem)->next; }