Innanzitutto bisogna ottimizzare e sistemare un po' il codice:
- dal punto di vista formale, al fine di rendere il codice più chiaro e leggibile, ti consiglio di rispettare la spaziatura e l'indentazione, di racchiudere sempre il corpo (anche se costituito da una sola riga di codice) di un'istruzione di controllo all'interno di parentesi graffe, di evitare tutti quei commenti e spazi bianchi;
- perchè non utilizzi un typedef per evitare di ripetere ogni volta la parola-chiave struct?
- per la dimensione delle parole sarebbe meglio definire una costante;
- la funzione srand() va richiamata una sola volta, quindi il suo posto non è certamente all'interno della funzione creaElemento();
- per un programma sulle liste concatenate sarebbe auspicabile prevedere una funzione per l'aggiunta di un nuovo elemento sia in testa che in coda. A tal proposito ti faccio notare che la funzione che aggiunge in coda può essere implementata sfruttando la funzione che aggiunge in testa;
- la funzione gestisciAggiunta() può essere evitata;
- la funzione stampaLista() si deve limitare a stampare la lista... non vedo il motivo per cui bisogna prima stampare la lista per assegnare gli id e calcolare il numero di vocali;
- per l'assegnazione degli id potresti per esempio utilizzare una variabile globale;
- la funzione creaElemento() può essere ampiamente ottimizzata... perchè utilizzare una seconda stringa per poi copiarla con strncpy()? Quale sarebbe l'utilità di memset()?
Alla luce di quanto appena detto io farei qualcosa del genere:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DIM 30
unsigned int ID = 0;
typedef struct nodo_
{
char c[DIM];
unsigned int id;
struct nodo_ *next;
} nodo;
void aggiungi_in_testa(nodo **head, nodo *nuovo)
{
if(nuovo)
{
nuovo->next = *head;
*head = nuovo;
}
}
void aggiungi_in_coda(nodo **head, nodo *nuovo)
{
nodo **temp = head;
while(*temp)
{
temp = &(*temp)->next;
}
aggiungi_in_testa(temp, nuovo);
}
nodo* crea_nuovo_elemento()
{
nodo *nuovo = malloc(sizeof(nodo));
if(nuovo)
{
unsigned int i;
for(i = 0; i < DIM - 1; ++i)
{
nuovo->c[i] = ('a' + rand() % 26);
}
nuovo->c[i] = '\0';
nuovo->id = ID++;
}
return nuovo;
}
void stampa_lista(nodo *head)
{
while(head)
{
printf("%d:\t%s\n", head->id, head->c);
head = head->next;
}
}
int main()
{
srand(time(0));
nodo *head = NULL;
for(unsigned int i = 0; i < 15; ++i)
{
aggiungi_in_coda(&head, crea_nuovo_elemento());
}
stampa_lista(head);
return 0;
}
se qualcosa non ti è chiaro chiedi pure.
Detto ciò qual è la tua idea per ordinare la lista?
Se la struct non può contenere altri membri e non vuoi tenere traccia del numero di vocali della singola stringa, andando un po' a discapito delle prestazioni potresti semplicemente sostituire
if(min_value->cntVocali < curr->cntVocali)
con
if(conta_vocali(min_value->c) < conta_vocali(curr->c))
dove
unsigned int conta_vocali(char *str)
{
...
}
è una funzione che ritorna il numero di vocali della stringa passata come argomento.