Funzione ricorsive in c
Scrivere una funzione in c,sia in versione iterativa che ricorsiva,che conta le occorrenze di un valore intero all'interno di una lista di variabili strutturate di tipo
a partire dall'indirizzo del suo primo elemento.
La mia soluzione iterativa è questa:
versione ricorsiva
sono corrette?
struct item{ int val; struct item *next; }
a partire dall'indirizzo del suo primo elemento.
La mia soluzione iterativa è questa:
int conta_lista(struct item *p,int valore) { int conta=0; /* ciclo di scansione */ while(p != NULL) { if(p->val==valore){conta++;} //verifico se il valore della lista è //è uguale a quello che voglio contare p = p->next; // scorre di un elemento } return conta; }
versione ricorsiva
int conta_lista(struct item *p,int valore) { int conta=0; if (p==NULL){ return conta;} if (p->val==valore){conta++;conta_lista(p->next,valore)} if (p->val!=valore){conta_lista(p->next,valore)} }
sono corrette?
Risposte
La versione iterativa mi sembra corretta, ma quella ricorsiva non lo è per niente. È pure strano che il compilatore non abbia trovato da ridire sul fatto che manchi il return nel caso in cui p sia diverso da NULL. Per prima cosa, conta non serve, anche nel tuo codice in pratica non la usi. Il metodo ricorsivo dovrebbe apparire come il seguente:
Il significato dovrebbe essere chiaro. Ma si può fare ancora di meglio sfruttando il modo in cui gli operatori relazionali funzionano in C: (a == b) ha come tipo int e vale 1 se la relazione è vera, 0 altrimenti. Nota che questo è cambiato in C++, per cui il seguente potrebbe non funzionare in C++ (non l'ho provato però e quindi potrebbe funzionare lo stesso per via di qualche cast implicito):
int conta_lista(struct item *p, int valore) { if (p == NULL) { return 0; } else if (p->val == valore) { return 1 + conta_lista(p->next, valore); } else { return 0 + conta_lista(p->next, valore); } }
Il significato dovrebbe essere chiaro. Ma si può fare ancora di meglio sfruttando il modo in cui gli operatori relazionali funzionano in C: (a == b) ha come tipo int e vale 1 se la relazione è vera, 0 altrimenti. Nota che questo è cambiato in C++, per cui il seguente potrebbe non funzionare in C++ (non l'ho provato però e quindi potrebbe funzionare lo stesso per via di qualche cast implicito):
int conta_lista(struct item *p, int valore) { if (p == NULL) return 0; else return (p->val == valore) + conta_lista(p->next, valore); }