PDA

Visualizza la versione completa : [C] Visualizzare elementi di una lista con una funzione ricorsiva


toni00c
17-01-2011, 17:50
ciao sto studiando un programma che permetta di creare una lista di stringhe concatenate
con lunghezza opzionale e successivamente le
stampi a video con una funzione ricorsiva ;
ora il problema è che la funzione ricorsiva ( ricerca) stampa a video solo l'ultimo elemento
della lista e non tutta

a questo punto mi chiedo dove sbaglio

questo è il codice ;










================================
typedef struct {
char value [11] ;
struct list *next ;
} list ; /* definisco la struttura */


typedef list *listPtr ;

void inserisci ( listPtr *Head , char valore [] , int size ) ;
void ricerca (listPtr headR ) ;





int main ()


{
listPtr Testa = NULL ; /* situazione iniziale non ci sono nodi */
int chooce ;
char parola [10] ;
int numeroStringhe = 0 ;




printf ("scegli 1 per uscire o premi un tasto per cominciare \n\n" ) ;
scanf ("%d" , & chooce ) ;



while (chooce != 1 )

{

fprintf (stdout , "\n\n") ;
inserisci ( &Testa , parola , 10) ;
numeroStringhe++ ;



scanf ("%d" , & chooce ) ;
}


ricerca (Testa ) ;



system ("PAUSE") ;


return 0 ;


}


void inserisci ( listPtr *Head , char valore [] , int size )

{
listPtr Nuovo ;


Nuovo = malloc ( sizeof ( list ) ) ;

if ( Nuovo != NULL )
{
if ( *Head == NULL )
{

*Head = Nuovo ;
fprintf (stdout , "inserisci la stringa o 1 per terminare\n") ;
gets ( Nuovo->value ) ;
Nuovo->next = NULL ;


}

else
{
(*Head)->next = Nuovo ;
fprintf (stdout , "inserisci la stringa o 1 per terminare\n") ;
gets ( Nuovo->value ) ;
Nuovo->next = NULL ;

}




} /* fine if */



}




void ricerca ( listPtr headR )
{

fprintf (stdout , "%s\n" , headR->value ) ;


while (headR->next != NULL ) /* cicla finche ci sono elementi */
{
headR = headR->next ;
ricerca ( headR) ;
}



}






altra domanda ; qual'è il modo migliore secondo voi per capire sta benedetta ricorsione ?

grazie

shodan
17-01-2011, 18:08
Ricordare che la ricorsione non prevede cicli per stabilire il punto d'uscita, ma solo if.
Nella tua funzione hai inserito un ciclo while di troppo che interferisce col meccanismo di ricorsione.


void ricerca ( listPtr headR )
{

if (headR == NULL) return;
ricerca ( headR->next);
fprintf (stdout , "%s\n" , headR->value ) ;

}

Non l'ho testata, ma dovrebbe essere giusta. Quando headR varrà NULL hai raggiunto la condizione di uscita, ricerca esce e stampa il valore corrispondente.
Se headR non è NULL, la funzione esegue le prime due linee di codice e richiama se stessa fino al raggiungimento della condizione.

toni00c
17-01-2011, 18:50
ciao ho letto la tua risposta e aggiunto due righe di codice al programma , ma per ora nulla ;
stampa solo l'ultimo valore a video





void inserisci ( listPtr *Head , char valore [] , int size )

{

listPtr Nuovo ;
listPtr precedente ;
====================
else
{
precedente = (*Head)->next ;
(*Head)->next = Nuovo ;
fprintf (stdout , "inserisci la stringa o 1 per terminare\n") ;
gets ( Nuovo->value ) ;
/*strcpy ( Nuovo->value , valore ) ; */
Nuovo->next = NULL ;

}




dev'essere uno dei soliti errori di sottofondo ; sono convinto di averla collegata bene la lista , ,ma proverò ancora
grazie

toni00c
17-01-2011, 20:26
problema risolto ; ho commesso un errore nella gestione della lista ;
ho deciso di inserire ogni nuovo stringa solo nella coda e questo è il codice completo del programma

la funzione ricorsiva funziona

grazie :)






typedef struct {
char value [11] ;
struct list *next ;
} list ;


typedef list *listPtr ;

void inserisci ( listPtr *Head , char valore [] , int size , listPtr *Succ ) ;
void ricerca (listPtr headR ) ; /*funzione ricorsiva */
void printList ( listPtr headR );


int main ()


{
listPtr Testa = NULL ;
listPtr successivo = NULL ;
int chooce ;
char parola [10] ;
int numeroStringhe = 0 ;




printf ("scegli 1 per uscire o premi un tasto per cominciare \n\n" ) ;
scanf ("%d" , & chooce ) ;

while (chooce != 1 )

{

fprintf (stdout , "\n\n") ;
inserisci ( &Testa , parola , 10 , &successivo) ;
numeroStringhe++ ;



scanf ("%d" , & chooce ) ;
}


ricerca (Testa ) ;

/*printList (Testa ) ;*/



system ("PAUSE") ;


return 0 ;



}


void inserisci ( listPtr *Head , char valore [] , int size , listPtr *Succ )

{
listPtr Nuovo ;






/* situazione iniziale non ci sono nodi */



Nuovo = malloc ( sizeof ( list ) ) ;

if ( Nuovo != NULL )
{
if ( *Head == NULL )
{

*Head = Nuovo ;


/* strcpy ( Nuovo->value , valore ) ; */
fprintf (stdout , "inserisci la stringa o 1 per terminare\n") ;
gets (Nuovo->value ) ;


}

else
{
(*Succ)->next = Nuovo ;

fprintf (stdout , "inserisci la stringa o 1 per terminare\n") ;
gets ( Nuovo->value ) ;
/*strcpy ( Nuovo->value , valore ) ; */
Nuovo->next = NULL ;


}

*Succ = Nuovo ;




} /* fine if */



}






void ricerca ( listPtr headR )
{

if (headR == NULL) return;
ricerca ( headR->next);
fprintf (stdout , "%s-->\n" , headR->value ) ;

}



void printList ( listPtr headR )


{

while ( headR != NULL )

{
fprintf (stdout , "%s -->" ,headR->value );
headR = headR->next ;
}


}

Laikius91
18-01-2011, 09:18
typedef struct {
char value [11] ;
struct list *next ;
} list ;

[....]

typedef list *listPtr ;


void inserisci ( listPtr *Head , char valore [] , int size , listPtr *Succ )

{
listPtr Nuovo ;

/* situazione iniziale non ci sono nodi */


Nuovo = malloc ( sizeof ( list ) ) ;

if ( Nuovo != NULL )
{
if ( *Head == NULL )
{

*Head = Nuovo ;


/* strcpy ( Nuovo->value , valore ) ; */
fprintf (stdout , "inserisci la stringa o 1 per terminare\n") ;
gets (Nuovo->value ) ;


}

else
{
(*Succ)->next = Nuovo ;

fprintf (stdout , "inserisci la stringa o 1 per terminare\n") ;
gets ( Nuovo->value ) ;
/*strcpy ( Nuovo->value , valore ) ; */
Nuovo->next = NULL ;


}

*Succ = Nuovo ;




} /* fine if */



}

[/QUOTE]


..solo una piccola precisazione, attenzione a come usi la malloc: questa restituisce un puntatore puro (void*), sarebbe corretto, per sicurezza farne sempre un cast esplicito.
quindi nella funzione inserisci, io specificherei:


Nuovo = (listPtr) malloc ( sizeof ( list ) )

Loading