In effetti non è semplicissimo!
Cmq ci ho riflettuto un po' e sono riuscito ad implementare la funzione (e senza aggiungere ulteriori membri alla struct list).
L'impostazione generale è la seguente:
void insert(list *l, int value)
{
node *nuovo = (node*)malloc(sizeof(node));
if(nuovo)
{
nuovo->data = value;
node *temp = l->head;
while(temp && value > temp->data)
{
temp = temp->next;
}
...
}
}
ovviamente ho omesso la parte relativa ai vari collegamenti.
Il mio approccio è stato quello di schematizzare tutti i casi possibili (ne ho contati 4):
1) aggiunta in testa in lista non vuota;
2) aggiunta in coda in lista non vuota;
3) aggiunta tra due nodi;
4) aggiunta in lista vuota.
Analizzandoli sono poi riuscito a ricavare uno schema generale valido per tutti e 4 i casi.
In pratica:
- inizio dall'assegnazione di nuovo->prev che varia in base al valore di temp (NULL o !NULL);
- a questo punto se nuovo->prev punta ad un nodo, bisognerà anche collegare quel nodo a nuovo;
- passo poi all'assegnazione di nuovo->next che è sempre la stessa in ogni caso;
- a questo punto se nuovo->next punta ad un nodo, bisognerà anche collegare quel nodo a nuovo, altrimenti (ossia nel caso in cui nuovo->next punti a NULL) bisognerà aggiornare la coda della lista (il membro tail in pratica);
- infine se occorre bisognerà aggiornare anche la testa della lista (ossia il membro head).