Stabilire crescenza lista

di Spark il
13 risposte
Salve, ho realizzato questo esercizio con le liste dove mi funzionano tutte le funzioni tranne la funzione CrescenzaSequenza(Lista l) che restituisce un segmentation fault. Dove ho sbagliato? Grazie.

Questa è la funzione:
int CrescenzaSequenza(Lista l){ //restituisce 1 se la sequenza è crescente, 0 se la sequenza è decrescente
	Nodo *temp = l;
	int trovato = 1;

	while (temp != NULL && trovato == 1){
		if (temp->dato > temp->prox->dato){
			trovato = 0;
		}
		temp = temp->prox;
	}
	printf("trovato> %d\n",trovato);
	return trovato;
}
Mentre questo è l'intero codice del programma:
#include <stdio.h>
#include <stdlib.h>
#define DIM 10

typedef struct Nodo{
	int dato;
	struct Nodo *prox;
}Nodo;

typedef Nodo *Lista;

Lista Inizializza();
Lista InserimentoCoda(Lista l, int e);
int NumeroPositivi(Lista l);
int NumeroNulli(Lista l);
int NumeroNegativi(Lista l);
int NumeroPari(Lista l);
int NumeroDispari(Lista l);
int CrescenzaSequenza(Lista l);
void StampaLista(Lista l);

int main(void){
	Lista l;
	int pos;
	int nul;
	int neg;
	int par;
	int dis;
	int cres;

	int i = 0;
	int Vett[DIM] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

	l = Inizializza();
	while (i < DIM){
		l = InserimentoCoda(l, Vett[i]);
		i++;
	}

	printf("Gli elementi inseriti nella lista sono i seguenti: \n");
	StampaLista(l);

	pos = NumeroPositivi(l); //restituisce il numero dei numeri positivi
	nul = NumeroNulli(l); //restituisce il numero dei numeri nulli
	neg = NumeroNegativi(l); //restituisce il numero dei numeri negativi
	par = NumeroPari(l); //restituisce il numero dei numeri pari
	dis = NumeroDispari(l); //restituisce il numero dei numeri dispari
	cres = CrescenzaSequenza(l); //restituisce 1 se la sequenza è crescente, 0 se la sequenza è decrescente

	printf("Il numero dei numeri positivi e' %d\n", pos);
	printf("Il numero dei numeri nulli e' %d\n", nul);
	printf("Il numero dei numeri negativi e' %d\n", neg);
	printf("Il numero dei numeri pari e' %d\n", par);
	printf("Il numero dei numeri dispari e' %d\n", dis);
	if (cres == 1){
		printf("La sequenza e' crescente\n");
	}else printf("La sequenza e' decrescente\n");

	system("pause");
	return 0;

}

Lista Inizializza(){
	return NULL;
}

void StampaLista(Lista l){
	Nodo *puntcorrente = l;
	while (puntcorrente != NULL){
		printf("elemento corrente> %d\n",puntcorrente->dato);
		puntcorrente = puntcorrente->prox;
	}
}

int ListaVuota(Lista l){
	return (l == NULL);
}

Lista InserimentoCoda(Lista l, int e){
	//creo un nodo, lo alloco, lo faccio puntare a NULL. L'ultimo nodo punterà al nodo creato
	//in questo modo il nuovo nodo è adesso l'ultimo elemento
	Nodo *temp;
	if(ListaVuota(l)) {
		//se la lista è vuota, il nodo andrà al primo posto
		temp = malloc(sizeof(Nodo));
		temp->dato = e;
		temp->prox = NULL;
	} else {
		temp = l;
		//ciclo per posizionarsi sull’ultimo elemento con prox==NULL
		while(temp->prox != NULL){
			temp = temp->prox;
		}
		//assegnazione nuovo nodo in ultima posizione
		temp->prox = malloc(sizeof(Nodo));
		temp->prox->dato = e;
		temp->prox->prox = NULL;
		temp = l;
	}
	return temp;
}

int NumeroPositivi(Lista l){
	Nodo *temp = l;
	int cont = 0;

	while (temp != NULL){
		if (temp->dato > 0){
			cont++;
		}
		temp = temp->prox;
	}

	printf("cont> %d\n",cont);
	return cont;
}

int NumeroNulli(Lista l){
	Nodo *temp = l;
	int cont = 0;

	while (temp != NULL){
		if (temp->dato == 0){
			cont++;
		}
		temp = temp->prox;
	}
	printf("cont> %d\n",cont);
	return cont;
}

int NumeroNegativi(Lista l){
	Nodo *temp = l;
	int cont = 0;

	while (temp != NULL){
		if (temp->dato < 0){
			cont++;
		}
		temp = temp->prox;
	}
	printf("cont> %d\n",cont);
	return cont;
}

int NumeroPari(Lista l){
	Nodo *temp = l;
	int cont = 0;

	while (temp != NULL){
		if ((temp->dato % 2) == 0){
			cont++;
		}
		temp = temp->prox;
	}
	printf("cont> %d\n",cont);
	return cont;
}

int NumeroDispari(Lista l){
	Nodo *temp = l;
	int cont = 0;

	while (temp != NULL){
		if ((temp->dato % 2) != 0){
			cont++;
		}
		temp = temp->prox;
	}
	printf("cont> %d\n",cont);
	return cont;
}

int CrescenzaSequenza(Lista l){ //restituisce 1 se la sequenza è crescente, 0 se la sequenza è decrescente
	Nodo *temp = l;
	int trovato = 1;

	while (temp != NULL && trovato == 1){
		if (temp->dato > temp->prox->dato){
			trovato = 0;
		}
		temp = temp->prox;
	}
	
	printf("trovato> %d\n",trovato);
	return trovato;
}

13 Risposte

  • Se temp->prox è NULL?
  • Esce dal ciclo while ?
  • No, la prima volta va in crash quando esegue temp->prox->dato
  • Intendi quando la lista è vuota? In questo caso non è vuota e comunque non mi funziona, in ogni caso posso aggiungere una sottofunzione che verifica se la lista è vuota.
  • Hai eseguito il codice con il debugger per capire in quale linea avviene l'errore?
  • Mi dice solo segmentation fault, e siccome mi stampa tutti i printf delle altre funzioni, il problema dovrebbe essere della funzione CrescenzaSequenza
  • Ti ripeto ... esegui con un debugger
  • Come ti ha detto NULL->[membro] non si può fare

    p.s.: monotonicità, non crescenza

    p.p.s.: crescente e non decrescente non sono sinonimi
  • Quindi mi conviene contare gli elementi e scrivere while ( i < NumeroElementi) ?
  • Banalmente così come controlli che temp non sia NULL dovrai controllare anche che temp->prox non sia NULL...
  • Ho risolto così:
    int MonotonicitàSequenza(Lista l){ //restituisce 0 se la lista è vuota, 1 se la sequenza è crescente, 2 se la sequenza è decrescente, 3 se non è ne decrescente ne crescente
    	Nodo *temp = l;
    	int trovato = 0;
    	int contc = 0, contd = 0, contn = 0;
    
    	if (temp == NULL){
    		trovato = 0;
    	}
    	else if (temp != NULL){
    		while (temp->prox != NULL){
    			if (temp->dato < temp->prox->dato){
    				contc++;
    				if (contc == ContareElementi(l) - 1){
    				trovato = 1;
    				}
    			}
    			if (temp->dato > temp->prox->dato){
    				contd++;
    				if (contd == ContareElementi(l) - 1){
    					trovato = 2;
    				}
    			}
    			if (temp->dato == temp->prox->dato){
    				contn++;
    				if (contn == ContareElementi(l)){
    					trovato = 3;
    				}
    			}
    			temp = temp->prox;
    		}
    		if (trovato == 0){
    			trovato = 4;
    	    }
    	}
    
    	printf("trovato> %d\n",trovato);
    	return trovato;
    }
    va bene ?
  • Se dici che hai risolto perché chiedi se va bene?
  • && è un operatore "short-circuit": se, ad esempio, scrivi while(temp != NULL && temp->prox != NULL), quando temp è NULL temp->prox non viene valutato e non vai in segmentation fault
Devi accedere o registrarti per scrivere nel forum
13 risposte