Funzione ricorsive in c

mictrt
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



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

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.