Se ti aiuti con uno schemino grafico su carta è semplice.
Ti scrivo i passi per una lista linkata singolarmente (ogni nodo punta al successivo, ma non al precedente).

1. Innanzitutto crei la tua struttura. Al suo interno ci vuole, oltre ai dati, un puntatore alla struttura stessa. Il giochino è fondamentalmente questo: ogni struttura ti indica (punta) a quella a lei successiva, quindi tu, avendo un puntatore alla prima della lista, puoi scorrerle tutte attraverso il puntatore. Cmq un po di codice...

struct myLinkedList {
int x;
struct myLinkedList *next;
} *first, *new;


Ho dichiarato anche due puntatori: il primo, first, come dice il nome, punta e punterà SEMPRE al primo elemento della lista. Non perderlo mai se no non hai modo di recuperarlo.

Il secondo puntatore lo usi per creare nuovi elementi, come indica il nome.

La prima cosa che ti conviene fare è first = NULL. In questo modo, quando andra ia scorrere la lista, e quindi tutti i suoi elementi, saprai quando fermarti proprio perchè sai che dopo quello che sarà ultimo ci sarà NULL.

Ed inoltre, se ci pensi, la lista è inizialmente vuota.

2. Creazione di un elemento.

if(!(new = (struct myLinkedList *)malloc(sizeof(struct myLinkedList))))
abort(); //errore nell'allocazione di memoria per il nuovo elemento.


Fatto ciò tu hai un nuovo elemento "vergine". Devi inizializzare i suoi campi e poi agganciarlo alla lista. Quindi new->x = 10;

3. Inserimento del nuovo elemento nella lista.
Qui c'è il trick di tutto ed entrano in gioco i puntatori. Tu hai first che punta al primo elemento della lista. first->next punta al secondo, first->next->next al terzo e cosi via.
Non importa quanti elementi ci siano, first punta sempre al primo. Se non vi sono elementi punta a NULL.

Quello che fai tu è dire a new che l'elemento a lui successivo è quello che ORA è primo
new->next = first;
...dopodichè aggiorni first in modo che punti al NUOVO primo elemento (perche ora first punta al secondo e a te serve che punti al primo, sempre), quindi...
first = new;

E' importante l'ordine dei due comandi, perche se lo inverti ti salta tutto.

4. Per scorrere gli elementi fai un ciclo finchè non trovi NULL...

struct myLinkedList *current;
current = first;
while(current != NULL)
current = current->next; //passo al successivo


E' importante creare un nuovo puntatore, perche se usi direttamente first poi perdi gli elementi.


Volendo puoi integrare una funzione di sorting che te la tenga costantemente ordinata.