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);
}