[C] stampare una lista all'inverso

di il
17 risposte

[C] stampare una lista all'inverso

Ciao a tutti, il problema chiede di inserire 10 caratteri da tastiera e di stampare la lista in senso inverso. Il codice è pressochè finito, ma al momento della stampa mi visualizza degli antipatici spazi che nessuno ha mai introdotto, vi posto il codice e l'esempio, se qualcuno può aiutarmi a individuare l'errore ve ne sarei grato.
#include <stdio.h>
#include <stdlib.h>

//definisco la struttura
struct charList{
    char value;
    struct charList *next;
};
//sinonimo di intList
typedef struct charList CharList;
typedef CharList *chList;

//prototipi di funzione
void insert (chList sPtr, char car);
void printList (chList l);
void printInverseList (chList l);

int main(int argc, char **argv){
    int i = 0;
    char value;
    chList l1;

    l1 = malloc(sizeof(struct charList));

    printf("*** FILL THE LIST WITH 10 CHAR ***\n\n");

//ciclo che mi fa inserire 10 caratteri da tastiera
    for(i = 0; i < 10; i++){
        printf("Enter a char: ");
        scanf("\n%c", &value);
        insert(l1, value);
    }

    printList(l1);

    printf("\n*** THE REVERSE LIST ***\n\n");

    printInverseList(l1);

	return 0;
}

//inserisce elementi nella lista
void insert(CharList *sPtr, char car){
    chList newPtr, currPtr, prevPtr;

    newPtr = malloc(sizeof(struct charList));

    if(newPtr != NULL){
        newPtr -> value = car;
        newPtr -> next = NULL;
        prevPtr = NULL;
        currPtr = sPtr;

        while(currPtr != NULL){
            prevPtr = currPtr;
            currPtr = currPtr -> next;
        }
        if(prevPtr == NULL){
            newPtr -> next = sPtr;
            sPtr = newPtr;
        }
        else{
            prevPtr -> next = newPtr;
            newPtr -> next = currPtr;
        }
    }
    else{
        printf("Not inserted. Memory not avalaible\n\n");
    }
}
//stampa la lista
void printList(chList l){
    if(l == NULL){
        printf("List is empty.\n");
    }
    else{
        while(l != NULL){
            printf(" %c -->", l -> value);
            l = l -> next;
        }
        printf("NULL\n\n");
    }
}
//ordina in senso inverso
void printInverseList (chList l){
    if(l == NULL){
        return;
    }
    else{
        printInverseList(l->next);
        printf(" --> %c ", l-> value);
    }

}
Immettendo i caratteri A, B, C, D, E, F, G, H, I, J visualizzo normalmente:

(spazio) --> A --> B --> C --> D --> E --> F --> G --> H --> I --> J --> NULL, ed è esattamente quello che vorrei, se non ci fosse quel fastidioso spazio.

Mentre per quanto riguarda la stampa inversa della lista visualizzo:

J --> I --> H --> G --> F --> E --> D --> C --> B --> A --> (spazio), nel secondo caso vorrei che al posto dello spazio stampasse un NULL, per far vedere che è finito il percorso inverso nella lista.

Spero di essere stato più chiaro possibile, grazie dell'aiuto.

17 Risposte

  • Re: [C] stampare una lista all'inverso

    Veramente la insert è sbagliata ...
  • Re: [C] stampare una lista all'inverso

    oregon ha scritto:


    Veramente la insert è sbagliata ...
    Aiuto fondamentale detto così.
  • Re: [C] stampare una lista all'inverso

    oregon ha scritto:


    Veramente la insert è sbagliata ...
    Avevo fatto confusione con le struct e le typedef, però ora ho risolto la cosa degli spazi.
    #include <stdio.h>
    #include <stdlib.h>
    
    //definisco la struttura
    struct charList{
        char value;
        struct charList *next;
    };
    //sinonimo di intList
    typedef struct charList CharList;
    typedef CharList *chList;
    
    //prototipi di funzione
    void insert (chList *sPtr, char car);
    void printList (CharList *l);
    void printInverseList (CharList *l);
    
    int main(int argc, char **argv){
        int i = 0;
        char value;
    
        chList *l1 = NULL;
    
        l1 = malloc(sizeof(struct charList));
    
        printf("*** FILL THE LIST WITH 10 CHAR ***\n\n");
    
    //ciclo che mi fa inserire 10 caratteri da tastiera
        for(i = 0; i < 10; i++){
            printf("Enter a char: ");
            scanf("\n%c", &value);
            insert(l1, value);
        }
    
        printList(*l1);
    
        printf("\n*** THE REVERSE LIST ***\n\n");
    
        printInverseList(*l1);
    
    	return 0;
    }
    
    //inserisce elementi nella lista
    void insert(chList *sPtr, char car){
        chList newPtr;
        chList currPtr;
        chList prevPtr;
    
        newPtr = malloc(sizeof(CharList));
    
        if(newPtr != NULL){
            newPtr -> value = car;
            newPtr -> next = NULL;
            prevPtr = NULL;
            currPtr = *sPtr;
    
        while(currPtr != NULL){
                prevPtr = currPtr;
                currPtr = currPtr -> next;
            }
            if(prevPtr == NULL){
                newPtr -> next = *sPtr;
                *sPtr = newPtr;
            }
             else{
                prevPtr -> next = newPtr;
                newPtr -> next = currPtr;
            }
        }
        else{
            printf("Not inserted. Memory not avalaible\n\n");
        }
    }
    //stampa la lista
    void printList(CharList *l){
        if(l == NULL){
            printf("List is empty.\n");
        }
        else{
            while(l != NULL){
                printf("%c --> ", l -> value);
                l = l -> next;
            }
            printf("NULL\n\n");
        }
    }
    //ordina in senso inverso
    void printInverseList (CharList *l){
        if(l == NULL){
            return;
        }
        else{
            printInverseList(l->next);
            printf("--> %c ", l-> value);
        }
    
    }
    
  • Re: [C] stampare una lista all'inverso

    JJBall ha scritto:


    oregon ha scritto:


    Veramente la insert è sbagliata ...
    Aiuto fondamentale detto così.
    Non ho avuto tempo di approfondire ma va in crash quindi non capisco come ti l'abbia eseguito ...
  • Re: [C] stampare una lista all'inverso

    Buonasera, io ho cercato di modificarlo in questo modo e sembra funzionare:
    #include <stdio.h>
     #include <malloc.h>
    
     struct nodo {
    	int info;
    	struct nodo *next;
     } *crea_lista(int n);
     
     void stampa_lista(struct nodo *s);
     void inverti_lista(struct nodo *s);
     
     int main() {
     	
     	int n;
     	struct nodo *lista;
     	printf("\n CREAZIONE DELLA LISTA\n");
     	printf("\n Digita gli elementi della lista --> ");
     	scanf("%d", &n);
    	 
    	lista = crea_lista(n);
    	
    	stampa_lista(lista);
    	
    	printf("\n La lista Invertita --> NULL ");
    	inverti_lista(lista);
    	
    	printf("\n\n");
     	system("PAUSE");
     	return 0;
     }
     
     struct nodo *crea_lista(int n) {
     	int i;
     	struct nodo *p, *pNext;
     	if(n == 0) {
     		p = NULL;
     		printf("\n LISTA VUOTA!");
    	 }
    	else {
    		p = (struct nodo *)malloc(sizeof(struct nodo));
    		printf("\n Inserisci il valore [1] --> ");
     		scanf("%d", &p->info);
     		pNext = p;
     		
    		for(i = 2; i <= n; i++) {
    			pNext->next = (struct nodo *)malloc(sizeof(struct nodo));
    			pNext = pNext->next;
    			printf("\n Inserisci il valore [%d] --> ", i);
    			scanf("%d", &pNext->info);
    		}
     	pNext->next = NULL;
     	}
     	return p;
     }
     
     void stampa_lista(struct nodo *s) {
      	printf("\n La Lista --> ");
      	while(s != NULL) {
      		printf(" |%d| ", s->info);
      		printf(" --> ");
      		s = s->next;
    	  }
    	  printf("NULL");
     }
  • Re: [C] stampare una lista all'inverso

    Buongiorno, al codice precedente ho implementato anche la funzione che stampa la lista invertita;
    solo che avrei una domanda, ma la funzione precisamente come andrebbe interpretata?
    Mi spiego meglio, scrivendo lista_inversa(r->next);, in effetti il programma dovrebbe partire dall'ultimo elemento (non NULL) e poi ad ogni iterazione legge il nodo precedente...(questa è una mia interpretazione e quindi non so se è corretta);
    in alternativa, avrei dovuto utilizzare anche un altro puntatore tipo pPrev che mi permetteva di contare dall'ultimo elemento?
    void lista_inversa(struct nodo *r) {
    	if(r != NULL) {
    		lista_inversa(r->next);
    		printf(" |%d| ", r->info);
    	}
    	else {
    		return;
    	}
    }
    Grazie anticipatamente per il chiarimento!
  • Re: [C] stampare una lista all'inverso

    Vincenzo.79 ha scritto:


    Buonasera, io ho cercato di modificarlo in questo modo e sembra funzionare: ...
    Ciao, ti faccio però notare che hai riesumato un topic che risale a ben 4 anni fa!

    Relativamente al codice io farei qualcosa del genere:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct nodo_
    {
        int info;
        struct nodo_ *next;
    }   nodo;
    
    void aggiungi_in_testa(nodo **p, const int a)
    {
        nodo *nuovo = (nodo*)malloc(sizeof(nodo));
        nuovo->info = a;
        nuovo->next = *p;
        *p = nuovo;
    }
    
    void stampa_lista(nodo *p)
    {
        while(p)
        {
            printf("%d ", p->info);
            p = p->next;
        }
    }
    
    void stampa_lista_invertita(nodo *p)
    {
        if(p)
        {
            stampa_lista_invertita(p->next);
            printf("%d ", p->info);
        }
    }
    
    int main()
    {
        nodo *lista = NULL;
        for(unsigned int n, i = 0; i < 5; ++i)
        {
            printf("n --> ");
            scanf("%d", &n);
            aggiungi_in_testa(&lista, n);
        }
        stampa_lista(lista);
        printf("\n");
        stampa_lista_invertita(lista);
        printf("\n");
        return 0;
    }

    Vincenzo.79 ha scritto:


    al codice precedente ho implementato anche la funzione che stampa la lista invertita;
    solo che avrei una domanda, ma la funzione precisamente come andrebbe interpretata?
    Mi spiego meglio, scrivendo lista_inversa(r->next);, in effetti il programma dovrebbe partire dall'ultimo elemento (non NULL) e poi ad ogni iterazione legge il nodo precedente...(questa è una mia interpretazione e quindi non so se è corretta);
    in alternativa, avrei dovuto utilizzare anche un altro puntatore tipo pPrev che mi permetteva di contare dall'ultimo elemento?
    Scusa, ma come fai a non capirne il funzionamento se l'hai implementata tu?!
    In ogni caso si tratta di un semplice esempio di funzione ricorsiva.
  • Re: [C] stampare una lista all'inverso

    Ciao, ti faccio però notare che hai riesumato un topic che risale a ben 4 anni fa!
    Ehh si non volevo generare un altro topic e prendermi un richiamo dai moderatori...
    Scusa, ma come fai a non capirne il funzionamento se l'hai implementata tu?!
    In ogni caso si tratta di un semplice esempio di funzione ricorsiva.
    Forse non mi sono spiegato...l'implementazione è chiara, solo che dovendo spiegare la funzione inverti_lista(), come fa a partire dall'ultimo elemento e poi risalire fino alla testa della lista, se non ho utilizzato nessuna struttura di controllo?
    E quindi ho cercato di dare una mia spiegazione...
    Spero di aver chiarito il mio dubbio...
    Grazie
  • Re: [C] stampare una lista all'inverso

    Vincenzo.79 ha scritto:


    Ciao, ti faccio però notare che hai riesumato un topic che risale a ben 4 anni fa!
    Ehh si non volevo generare un altro topic e prendermi un richiamo dai moderatori...
    Cito il regolamento:
    3) Non riaprire thread datati
    A meno che non si tratti di thread "didattici" il cui contributo nel tempo può essere costruttivo, è da evitare la riesumazione di vecchie discussioni
    Comunque fa niente, figurati... o almeno penso, non sono un moderatore!

    Vincenzo.79 ha scritto:


    Forse non mi sono spiegato...l'implementazione è chiara, solo che dovendo spiegare la funzione inverti_lista(), come fa a partire dall'ultimo elemento e poi risalire fino alla testa della lista, se non ho utilizzato nessuna struttura di controllo?
    E quindi ho cercato di dare una mia spiegazione...
    Spero di aver chiarito il mio dubbio...
    Scusami, ma continuo a non capire... di solito si azzarda una propria spiegazione quando un argomento non è chiaro, il che cozza con il

    Vincenzo.79 ha scritto:


    Buongiorno, al codice precedente ho implementato anche la funzione che stampa la lista invertita;
    del tuo precedente messaggio.
    La questione di fondo secondo me resta la seguente: conosci la ricorsione?
  • Re: [C] stampare una lista all'inverso

    Forse ho posto male la domanda (e sicuramente sono io che non riesco a farmi capire): perchè passando come argomento (l->next) alla funzione ricorsiva inverti(), tale funzione legge dalla coda?
    // Funzione Ricorsiva che inverte la lista creata
    void inverti(struct nodo *l) {
    	if(l != NULL) {
    		/* 
    			La funzione ricorsiva (funzione che richiama se stessa) deve essere inserita 
    			in questo preciso punto altrimenti in fase di esecuzione, il programma 
    			stampa la lista originale e non quella inversa!
    		*/
    		inverti(l->next);
    		printf(" |%d| ", l->info);
    	}
    }
    NB: per la riesumazione dei vecchi post mi era sfuggita questa parte...cmq per ora i moderatori non mi hanno richiamato, evidentemente il post non è proprio così vecchio!
  • Re: [C] stampare una lista all'inverso

    Vincenzo.79 ha scritto:


    Forse ho posto male la domanda (e sicuramente sono io che non riesco a farmi capire): perchè passando come argomento (l->next) alla funzione ricorsiva inverti(), tale funzione legge dalla coda?
    La mia perplessità nasce dal fatto che hai detto di aver implementato una funzione di cui però non ne comprendi fino in fondo il funzionamento, e sinceramente proprio non capisco come si faccia ad implementare un algoritmo se non si ha ben chiaro quello che si sta facendo...
    In ogni caso, tralasciando quale sia l'origine della funzione ricorsiva da te postata, cerco di rispondere alla tua domanda con il seguente schema: https://i.postimg.cc/k4WjjzF5/ee.pn
  • Re: [C] stampare una lista all'inverso

    09/08/2022 - Nippolo ha scritto:


    Vincenzo.79 ha scritto:


    Forse ho posto male la domanda (e sicuramente sono io che non riesco a farmi capire): perchè passando come argomento (l->next) alla funzione ricorsiva inverti(), tale funzione legge dalla coda?

    La mia perplessità nasce dal fatto che hai detto di aver implementato una funzione di cui però non ne comprendi fino in fondo il funzionamento, e sinceramente proprio non capisco come si faccia ad implementare un algoritmo se non si ha ben chiaro quello che si sta facendo...
    In ogni caso, tralasciando quale sia l'origine della funzione ricorsiva da te postata, cerco di rispondere alla tua domanda con il seguente schema: https://i.postimg.cc/k4WjjzF5/ee.p

    Visto il disegnino molto carino, ma la cosa dove mi blocco se devo leggere una lista invertita e punto con *p alla testa della lista, digitando p?info non dovrei andarmi a prendere l'elemento successivo, e non quello precedente?

    scusami se insisto…sono certo che se abbatto questo muro riuscirò a fare gli altri esercizi sulle liste…

  • Re: [C] stampare una lista all'inverso

    Ma scrivi qui sempre dopo un anno?

    Fra l'altro non si capisce la domanda che fai

  • Re: [C] stampare una lista all'inverso

    21/07/2023 - oregon ha scritto:


    Ma scrivi qui sempre dopo un anno?

    Fra l'altro non si capisce la domanda che fai

    E' stato un periodaccio, ho da poco ripreso…se poi vuoi i dettagli…ma non credo siano inerenti alla discussione del forum…

    Cmq hai ragione…la domanda riguarda sempre lo sviluppo di una funzione che genera una lista invertita…

Devi accedere o registrarti per scrivere nel forum
17 risposte