Lista circolare in c

di il
3 risposte

Lista circolare in c

Salve,
questo programmino che dovrebbe creare una lista circolare contenente i caratteri dall alfabeto senza dummy in quanco la testa è sottinteso che sia noda che contiene 'a' mi solleva il segmentation faul quando provo ad unire la coda con la testa nella funzione inizializza e anche se invoco la funzione add

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct listNode{
	char data;
	struct listNode *nextPtr;
	};
typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;

void insert(ListNodePtr *l,char c){
	ListNodePtr newPtr=NULL;
	newPtr = (ListNodePtr)malloc(sizeof(ListNode));
	if(newPtr != NULL){
		newPtr->data = c;
		newPtr->nextPtr = *l;
		*l = newPtr;
		}
	else
		printf("memoria non disponibile..\n");
	}
void stampa(ListNodePtr l){
	if(l == NULL)
		printf("la lista è vuota..\n");
	else
		while(l->data != '9'){
			printf("%c  ",l->data);
			l = l->nextPtr;
			}
	printf("\n\n");
	}
void add(ListNodePtr *l,char c){
	ListNodePtr tempPtr,newPtr;
	tempPtr = *l;
	newPtr = (ListNodePtr)malloc(sizeof(ListNode));
	if(newPtr != NULL){
		newPtr->data = c;
		newPtr->nextPtr = NULL;
		while(tempPtr->nextPtr != NULL)
			tempPtr->nextPtr = newPtr;
		}
	else printf("memoria non disponibile..\n\n");
	}
	

void inizializza(ListNodePtr *l){//a: 97; z: 122; 0: 48; 9: 57
	char c;
	ListNodePtr tempPtr=*l;
	for(c='9';c >= '0';c--) insert(l,c);
	for(c='z';c >='a';c--)  insert(l,c);
	while(tempPtr->data != '9')
		tempPtr = tempPtr->nextPtr;
	tempPtr->nextPtr = *l;
	}
		
int main(void){
	ListNodePtr l=NULL;
	inizializza(&l);
	stampa(l);
	return 0;
	}

3 Risposte

  • Re: Lista circolare in c

    Ciao,
    ecco una versione più corretta del codice:
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    struct listNode{
    	char data;
    	struct listNode *nextPtr;
    };
    typedef struct listNode ListNode;
    typedef ListNode *ListNodePtr;
    
    void insert(ListNodePtr *l, char c)
    {
    	ListNodePtr newPtr = NULL;
    	newPtr = (ListNodePtr) malloc(sizeof(ListNode));
    	if(newPtr != NULL)
    	{
    		newPtr->data = c;
    		newPtr->nextPtr = *l;
    		*l = newPtr;
    	}
    	else
    		printf("memoria non disponibile..\n");
    }
    
    void stampa(ListNodePtr l)
    {
    	/* tengo traccia del primo elemento della lista */
    	char primo_elemento = l->data;
    	if(l == NULL)
    		printf("la lista è vuota..\n");
    	else
    	{
    		do
    		{
    			printf("%c  ",l->data);
    			l = l->nextPtr;
    		}
    		/* finche' non ritrovo il primo elemento */
    		while(l->data != primo_elemento);
    	}
    	printf("\n\n");
    }
    
    /*
    void add(ListNodePtr *l, char c){
    	ListNodePtr tempPtr, newPtr;
    	tempPtr = *l;
    	newPtr = (ListNodePtr) malloc(sizeof(ListNode));
    	if(newPtr != NULL){
    		newPtr->data = c;
    		newPtr->nextPtr = NULL;
    		while(tempPtr->nextPtr != NULL)
    			tempPtr->nextPtr = newPtr;
    	}
    	else printf("memoria non disponibile..\n\n");
    }
    */
    
    
    void inizializza(ListNodePtr *l){//a: 97; z: 122; 0: 48; 9: 57
    	char c;
    	for(c='9'; c >= '0'; c--) insert(l,c);
    	for(c='z'; c >='a'; c--)  insert(l,c);
    	
    	/* collego la coda alla testa */
    	ListNodePtr tempPtr = *l;
    	while(tempPtr->nextPtr != NULL)
    		tempPtr = tempPtr->nextPtr;
    	tempPtr->nextPtr = *l;
    }
    
    int main(void){
    	ListNodePtr l = NULL;
    	inizializza(&l);
    	stampa(l);
    	return 0;
    }
    
    Ho fatto qualche modifica alla funzione di stampa, anche se l'errore principale era nella funzione inizializza. Infatti tu prendevi un riferimento alla lista, facendo
    
    ListNodePtr tempPtr = *l;
    
    POI facevi delle chiamate alla funzione insert che andava a modificare la lista. In seguito utilizzavi il riferimento "l", che però non era più quello di prima. Riordinando le righe di codice si ottiene il comportamento atteso.
    Diciamo che probabilmente la cosa più semplice era creare un metodo "chiudi_lista" a cui passare un puntatore alla lista e che si occupasse di collegare la coda alla testa per chiudere il cerchio.

    Per quanto riguarda la funzione add, mi sono limitato a commentarla. Ti faccio però notare che scrivere
    
    	if(newPtr != NULL){
    		newPtr->data = c;
    		newPtr->nextPtr = NULL;
    		while(tempPtr->nextPtr != NULL)
    			tempPtr->nextPtr = newPtr;
    	}
    
    non ha senso, visto quel while non fa nulla: passa da un nodo al successivo... e poi?

    Se hai altri dubbi, chiedi pure.
    Ciao.
  • Re: Lista circolare in c

    Prima di tutto grazie per la risposta esaustiva,
    ho modificato il codice ma la procedura add mi da ancora errore in esecuzione
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    struct listNode{
    	char data;
    	struct listNode *nextPtr;
    	};
    typedef struct listNode ListNode;
    typedef ListNode *ListNodePtr;
    
    void insert(ListNodePtr *l,char c){
    	ListNodePtr newPtr=NULL;
    	newPtr = (ListNodePtr)malloc(sizeof(ListNode));
    	if(newPtr != NULL){
    		newPtr->data = c;
    		newPtr->nextPtr = *l;
    		*l = newPtr;
    		}
    	else
    		printf("memoria non disponibile..\n");
    	}
    void stampa(ListNodePtr l){
    	char c;
    	if(l == NULL)
    		printf("la lista è vuota..\n\n");
    	else{
    		c = l->data;
    		do{
    			printf("%c  ",l->data);
    			l = l->nextPtr;
    			}
    		while(l->data != c);
    		printf("\n\n");
    		}
    	}
    
    void chiudiLista(ListNodePtr *l){
    	ListNodePtr tempPtr;
    	tempPtr = *l;
    	while(tempPtr->data != '9')
    		tempPtr = tempPtr->nextPtr;
    	tempPtr->nextPtr = *l;
    	}
    void add(ListNodePtr *l,char c){
    	ListNodePtr tempPtr,newPtr;
    	tempPtr = *l;
    	newPtr = (ListNodePtr)malloc(sizeof(ListNode));
    	if(newPtr != NULL){
    		newPtr->data = c;
    		newPtr->nextPtr = NULL;
    		while(tempPtr->nextPtr != NULL)
    			tempPtr = tempPtr->nextPtr;
    		tempPtr->nextPtr = newPtr;
    		chiudiLista(l);
    		
    		}
    	else printf("memoria non disponibile..\n\n");
    	}
    	
    	
    
    void inizializza(ListNodePtr *l){//a: 97; z: 122; 0: 48; 9: 57
    	char c;
    	for(c='9';c >= '0';c--) insert(l,c);
    	for(c='z';c >='a';c--)  insert(l,c);
    	//chiudo la lista
    	chiudiLista(l);
    	}
    		
    int main(void){
    	ListNodePtr l=NULL;
    	//inizializza(&l);
    	//stampa(l);
    	add(&l,'a');
    	add(&l,'e');
    	printf("%c",l->data);
    	free(l);
    	return 0;
    	}
    
    
  • Re: Lista circolare in c

    Se ho ben capito, la tua funzione add dovrebbe eseguire un inserimento in coda alla lista.
    Questo codice dovrebbe funzionare correttamente:
    
    void add(ListNodePtr *l, char c){
    	ListNodePtr tempPtr, newPtr;
    	tempPtr = *l;
    	newPtr = (ListNodePtr) malloc(sizeof(ListNode));
    	
    	if(newPtr != NULL){
    		newPtr->data = c;
    		newPtr->nextPtr = NULL;
    		
    		/* se la lista e' vuota */
    		if(*l == NULL)
    		{
    			*l = newPtr;
    		}
    		else
    		{
    			/* scorro la lista fino alla fine */
    			while(tempPtr->nextPtr != NULL)
    				tempPtr = tempPtr->nextPtr;
    				
    			/* aggiungo il nuovo nodo in fondo alla lista */
    			tempPtr->nextPtr = newPtr;
    		}
    	}
    	else printf("memoria non disponibile..\n\n");
    }
Devi accedere o registrarti per scrivere nel forum
3 risposte