ordinamento lista c

roger21

Nuovo Utente
21
3
Codice:
 /** velocità della luce (m/s)*/
#define  V  299792458.
/** costante di conversione radianti --> gradi */
#define RAD2DEG 57.29577951308232

/**
 Valori booleani */
typedef enum { FALSE=0, TRUE=1  } bool_t;

/** tipi di ordinamento:
 NOTORD = nessun ordinamento.
 TIME = ordinata per tempi crescenti.
 POSITION = ordinata per posizione crescente
 */
typedef enum { NOTORD=0, TIME=1, POSITION=2  } ord_t;

/** flag che indica se la rilevazione contiene rumore (NOISE) o no (OK) */
typedef enum { OK=0, NOISE=2  } flag_t;

/** struttura che realizza l'elemento della lista di registrazioni */
typedef struct elem {
    /** posizione registrazione*/
    double position;
    /** tempo registrazione */
    double time;
    /** flag rumore/buono */
    flag_t flag;
    /** puntatore al prossimo elemento */
    struct elem * next;
} elem_t;

/** struttura della lista delle registrazioni */
typedef struct {
    /** puntatore alla testa della lista */
    elem_t * head;
    /** numero di elementi presenti in lista */
    int nelem;
    /** indica se è ordinata e se l'ordinamento e' rispetto al tempo o alla posizione  */
    ord_t ord;
} lista_t;


lista_t * new_lista ( void ) {
    
    lista_t * l ;
    
    
    if ( (  l = malloc (sizeof ( lista_t ) ) ) == NULL ) {
        return NULL;
    }
    
    l->head = NULL ;
    l->ord = NOTORD;
    return l;
}


static void stampa_lista_r ( FILE * f, elem_t * h ) {
    if ( h == NULL ) {
        return ;
    }
    if ( h->flag == OK ) fprintf(f,"::(%.1f,%.15f,OK)\n",h->position, h->time);
    if ( h->flag == NOISE ) fprintf(f,"::(%.1f,%.15f,NOISE)\n",h->position, h->time);
    stampa_lista_r(f, h->next);
}

void stampa_lista ( FILE * f, lista_t * l ) {
    
    if ( l == NULL ) return ;
    
    if ( l-> head == NULL ) {
        fprintf(stdout,"Lista vuota.\n");
        return ;
    }
    stampa_lista_r (f,l->head);
    putchar('\n');
    return ;  
}


/**
 legge da file una nuova registrazione (notare il formato analizzando il file dati, ogni registrazione è terminata da '\n')
 se il formato è corretto e la conversione è possibile alloca una struttura di tipo elem_t
 inizializzando i campi con i valori cotenuti nella riga (nota: il campo next va inizializzato a NULL)
 se il formato della riga non e' corretto, si è raggiunto EOF o si è verificato un errore lo segnala ritornando NULL
 
 \param fd descrittore del file
 
 \retval p puntatore alla struttura allocata (!= NULL) se tutto è andato bene
 \retval NULL se si è verificato un errore
 
 */
elem_t* leggi_registrazione (FILE* fd){
    elem_t* p;
    double x, y;
    flag_t k;
    if( fd==NULL ) {
        perror("Errore in apertura del file");
    }
    
    fscanf(fd, "%lf %lf %d", &x, &y, &k);
    p = malloc(sizeof (elem_t));
    if(p==NULL) return NULL;
    else{
        (*p).position = x;
        (*p).time = y;
        (*p).flag = k;
        (*p).next = NULL;}
    return p;
}

/**
 inserisce nella lista
 -- se la lista non e' ordinata inserisce in testa alla lista
 --  se la lista e' ordinata per posizione (crescente) e se la lista e'  ordinata per tempo (crescente) inserisce mantenendo la lista ordinata
 
 \param pelem puntatore all'elemento da inserire
 
 \retval -1 se si e' verificato un errore nell'allocazione del nuovo elemento
 \retval 0 altrimenti
 */
void insert(elem_t**p,elem_t*el){
    (*el).next = *p;
    (*p) = &(*el);}

void inserisci_time(elem_t **p,elem_t *el) {
    if((*p)==NULL || (**p).time > (*el).time)
        insert(p, el);
    else inserisci_time(&(**p).next, el);}
void inserisci_position(elem_t**p,elem_t *el){
    if((*p)==NULL || (**p).position > (*el).position)
        insert(p, el);
    else inserisci_position(&(**p).next, el);}

int inserisci(lista_t*l,elem_t*pelem) {
    ord_t ord;elem_t *el,**p;
            if (ord==TIME) inserisci_time(**p,*el);
    else if(ord==NOTORD)inserisci(l,l->head);
    else if(ord==POSITION)inserisci_position(**p,*el);
    else return -1;
    return 0;}


/**
 mette a false il campo ord per indicare che la lista non e' piu' ordinata
 \param l lista
 
 */
void set_nonordinata (lista_t * l) {
    (*l).ord = NOTORD;
}


/**
 se la lista non e' ordinata rispetto al tempo setta a TIME il campo ord
 ed ordina la lista, altrimenti non fa niente
 \param l lista
 
 */
void set_ordinata_time (lista_t * l) {
    lista_t tmp;
    if((*l).ord == TIME);
    else {
        (*l).ord = TIME;
        while (l->head != NULL) {inserisci(&(tmp.head), l->head);}
        (*l).head = tmp.head;
    }
}

/**
 se la lista non e' ordinata rispetto alla posizione setta a POSITION
 il campo ord  ed ordina la lista, altrimenti non fa niente
 \param l lista
 
 */
void set_ordinata_position (lista_t * l) {
    lista_t tmp;
    if((*l).ord == POSITION);
    else {
        (*l).ord = POSITION;
        while(l->head != NULL) {inserisci(&(tmp.head), l->head);}
        (*l).head = tmp.head;
    }
}

/**
 dealloca tutti gli elementi della lista, la struttura lista e annulla il puntatore alla lista stessa
 
 \param pl puntatore al putatore della lista da deallocare
 
 */
void free_lista (lista_t **pl) {
    elem_t *tmp;
    elem_t*p;
    p=(**pl).head;
    while(p!=NULL){tmp=(*p).next;
        free(p);
        p=tmp;}
    free(*pl);
    (*pl)=NULL;}

/**
 calcola \theta invertendo la formula
 
 t_i - t_j = (x_i - x_j)/2 sin(\theta)
 
 \param pi  putatore all'elemento relativo alla rilevazione  i
 \param pj  puntatore all'elemento relativo alla rilevazione j
 \item pth  puntatore alla variabile che conterra' il valore di theta (non viene modificata se si verifica un errore ) in GRADI
 
 \retval 0 se il valore di theta e' calcolabile (se l'arcsin e' definito)
 \retval -1 altrimenti
 
 */
int compute_theta (elem_t* pi, elem_t* pj, double* pth) {
    double t_i, t_j, p_i, p_j, Th, tot;
    t_i = (*pi).time;
    t_j = (*pj).time;
    p_i = (*pi).position;
    p_j = (*pj).position;//qui continua a dirmi che i tipo double non è una funzione o un puntatore,boh,comunque errore
    tot = (V*(t_i - t_j))/(p_i - p_j);
    Th = asin(tot);
    Th = Th*RAD2DEG;
    return Th;
}
/**
 calcola la media dei valori in un file
 
 \param f file in cui leggere i valori (non viene modificato)
 \param pm puntatore alla variabile che conterrà la media
 
 
 \retval 1 se tutto è andato bene
 \retval 0 se si è verificato un errore
 
 */

elem_t* leggi_registrazione_2 (FILE* f){
    elem_t* p;
    double x, y;
    flag_t k;
    if( f==NULL ) {
        perror("Errore in apertura del file");
    }
    
    fscanf(f, "%lf %lf %d", &x, &y, &k);
    p = malloc(sizeof (elem_t));
    if(p==NULL) return NULL;
    else{
        (*p).position = x;
        (*p).time = 0;
        (*p).flag = 0;
        (*p).next = NULL;}
    return p;
}

int media (FILE * f, double* pm) {
    double sum=0,media;
    elem_t* leggi_registrazione_2 (FILE* f){
        int inserisci(lista_t*l,elem_t*pelem); }
    while(p!=NULL) {elem_t* leggi_registrazione_2 (&f)
    sum += p->position;
        media = sum/nelem;}
return media;
}

/**
 calcola la deviazione standard dei valori in un file
 
 \param f file in cui leggere i valori (non viene modificato)
 \param ps puntatore alla variabile che conterrà la varianza
 \param m media
 
 
 \retval 1 se tutto è andato bene
 \retval 0 se si è verificato un errore
 
 */
int deviazione (FILE * f, double* ps, double m);
{double tmp, devstd,m;int i;
    fscanf(f,"%lf",&tmp);
    m=media(f,pm);
    devstd=((tmp-media)*(tmp-media))
    while tmp != NULL;
        for(i=0;i<nelem;i++){devstd=devstd/(nelem-1);}

#endif

Salve,dunque ho questo codice da consegnare a brevissimo,il main è a parte,qui ci sono solo le funzioni,si tratta principalmente di ordinare una lista per tempi e posizioni presenti in un file fornito,attraverso cui calcolare una serie di corrispondenti angoli di incidenza(per ogni posizione e tempo) facendone media e deviazione standard,il main per testare le funzioni da parecchi problemi soprattutto relativamente ai tipi dei parametri(che sono elementi di strutture) e ai puntatori,i grossi dubbi sono legati al fatto che avendo ricevuto una grossa mano da un amico non so bene come funzionano i puntatori e i doppi puntatori nelle liste,chi avesse la bontà di ravvisare qualcosa mi farebbe un enorme favore,grazie.
 

rodhellas

Utente Èlite
1,522
427
CPU
Ryzen 5 3600
Dissipatore
GELID Phantom
Scheda Madre
MSI B450 Gaming Plus Max
HDD
500GB m.2 + 2TB HDD
RAM
16GB Corsair LPX 3000mhz
GPU
Gigabyte GTX 960 OC
Audio
Integrata
Monitor
SyncMaster 223BW
PSU
Antec HCG-520M
Case
Meshify C
Net
Gigabit Fastweb
OS
Windows 10 64bit
Non so come funziono i doppi puntatori (posso immaginare ma non li ho mai provati), comunque una lista è composta da un nodo (cioè una struttura contenente un puntatore e tot variabili (int, char, float, ecc)). Ora, supponendo tu sappia allocare dinamicamente la memoria (malloc e free), ipotizziamo questo esempio:
Codice:
struct node_t {
int value;
struct node_t *next;
}
Crei il primo nodo: in value ci metti quello che devi mettere, e fai puntare il nodo a NULL (essendo il primo). Ora vuoi creare il nodo B, in modo che venga successivamente al nodo A: crei il nodo B, lo fai puntare a NULL e il puntatore del nodo A lo fai puntare al nodo B. E via cosi, se volessi mettere il nodo C in mezzo ad A e B, punta A a C, e C a B.
Dal tuo codice, ho visto che usi comunque (*puntatore).qualcosa, è molto più comodo scrivere "qualcosa->puntatore"
 

roger21

Nuovo Utente
21
3
Non so come funziono i doppi puntatori (posso immaginare ma non li ho mai provati), comunque una lista è composta da un nodo (cioè una struttura contenente un puntatore e tot variabili (int, char, float, ecc)). Ora, supponendo tu sappia allocare dinamicamente la memoria (malloc e free), ipotizziamo questo esempio:
Codice:
struct node_t {
int value;
struct node_t *next;
}
Crei il primo nodo: in value ci metti quello che devi mettere, e fai puntare il nodo a NULL (essendo il primo). Ora vuoi creare il nodo B, in modo che venga successivamente al nodo A: crei il nodo B, lo fai puntare a NULL e il puntatore del nodo A lo fai puntare al nodo B. E via cosi, se volessi mettere il nodo C in mezzo ad A e B, punta A a C, e C a B.
Dal tuo codice, ho visto che usi comunque (*puntatore).qualcosa, è molto più comodo scrivere "qualcosa->puntatore"

scusa se rispondo solo ora,grazie,proverò a sfruttare il tuo hint per cercare di far girare il codice,vediamo...

- - - Updated - - -

ho provato a correggere,tuttavia i test per le funzioni continuano a dare esito negativo,qualche idea?
Codice:
 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
/** velocità della luce (m/s)*/
#define  V  299792458.
/** costante di conversione radianti --> gradi */
#define RAD2DEG 57.29577951308232

/**
 Valori booleani */
typedef enum { FALSE=0, TRUE=1  } bool_t;

/** tipi di ordinamento:
 NOTORD = nessun ordinamento.
 TIME = ordinata per tempi crescenti.
 POSITION = ordinata per posizione crescente
 */
typedef enum { NOTORD=0, TIME=1, POSITION=2  } ord_t;

/** flag che indica se la rilevazione contiene rumore (NOISE) o no (OK) */
typedef enum { OK=0, NOISE=2  } flag_t;

/** struttura che realizza l'elemento della lista di registrazioni */
typedef struct elem {
    /** posizione registrazione*/
    double position;
    /** tempo registrazione */
    double time;
    /** flag rumore/buono */
    flag_t flag;
    /** puntatore al prossimo elemento */
    struct elem * next;
} elem_t;

/** struttura della lista delle registrazioni */
typedef struct {
    /** puntatore alla testa della lista */
    elem_t * head;
    /** numero di elementi presenti in lista */
    int nelem;
    /** indica se è ordinata e se l'ordinamento e' rispetto al tempo o alla posizione  */
    ord_t ord;
} lista_t;


lista_t * new_lista ( void ) {
    
    lista_t * l ;
    
    
    if ( (  l = malloc (sizeof ( lista_t ) ) ) == NULL ) {
        return NULL;
    }
    
    l->head = NULL ;
    l->ord = NOTORD;
    return l;
}


static void stampa_lista_r ( FILE * f, elem_t * h ) {
    if ( h == NULL ) {
        return ;
    }
    if ( h->flag == OK ) fprintf(f,"::(%.1f,%.15f,OK)\n",h->position, h->time);
    if ( h->flag == NOISE ) fprintf(f,"::(%.1f,%.15f,NOISE)\n",h->position, h->time);
    stampa_lista_r(f, h->next);
}

void stampa_lista ( FILE * f, lista_t * l ) {
    
    if ( l == NULL ) return ;
    
    if ( l-> head == NULL ) {
        fprintf(stdout,"Lista vuota.\n");
        return ;
    }
    stampa_lista_r (f,l->head);
    putchar('\n');
    return ;
}

//Questo codice è stato realizzato da Ruggero Cusimano, numero di matricola 501417, e Filippo Cancellotti, numero di matricola 505500. Corso Informatica Primo Anno. Si dichiara che il contenuto di questo file e' in ogni sua parte opera originale degli autori.

elem_t* leggi_registrazione (FILE* fd){  //legge da FILE la registrazione e restituisce un puntatore ad un elemento
    elem_t* p;
    double x, y;
    flag_t k;
    if( fd==NULL ) {
        perror("Errore in apertura del file");
    }
    
    fscanf(fd, "%lf %lf %d", &x, &y, &k); //la funzione fscanf permette di associare ai caratteri letti nel FILE dei valori numerici, questi valori vengono associati alle tre variabili, due double e un intero
    p = malloc(sizeof (elem_t));  //quanto ottenuto viene allocato nell' heap tramite malloc
    if(p==NULL) return NULL;
    else{
        p->position = x; //associo i valori letti dal FILE alle varie componenti della struttura del tipo elem_t per inizializzarne i campi
        p->time = y;
        p->flag = k;
        p->next = NULL;}
    return p;
}


void insert(elem_t**p,elem_t*el){   //questa funzione permette di procedere associando un puntatore a p al campo next
    el->next = *p;
    (*p) = &(*el);}

void inserisci_time(elem_t **p,elem_t *el) { //funzione che permette l'inserimento dei dati in maniera ordinata rispetto al tempo
    if((*p)==NULL || (**p).time > el->time)  //controlla se l'ultimo valorore letto sia maggiore o minore dei precedenti e se il FILE è finito
        insert(p, el);
    else inserisci_time(&(**p).next, el);}   //in caso contrario l'elemento viene associato alla head della lista
void inserisci_position(elem_t**p,elem_t *el){  //funzione analoga alla precedente che permette però la l'inserimento ordinato dal punto di vista delle posizioni
    if((*p)==NULL || (**p).position > el->position)
        insert(p, el);
    else inserisci_position(&(**p).next, el);}

int inserisci(lista_t*l,elem_t*pelem) { //esegue l'inserimento distinguendo i casi a seconda di cosa si trovi nel campo ord della lista
    ord_t ord;elem_t *el,**p;lista_t *li;
    if (ord==TIME) inserisci_time(p,el);  //la serie di if else controlla cosa si trovi nel campo ord
    else if(ord==NOTORD)inserisci(l,l->head);
    else if(ord==POSITION)inserisci_position(p,el);
    else return -1;
    return 0;}


void set_nonordinata (lista_t * l) {
    l->ord = NOTORD;  //setta a NOTORD il campo ord
}


void set_ordinata_time (lista_t * l) { //ordina la lista per tempo, se non lo è già
    lista_t tmp;
    if(l->ord == TIME);
    else {
        l->ord = TIME;  //se la lista non è già ordinata per tempo setta ord a TIME
        while (l->head != NULL) {inserisci(l->head,&(*tmp.head));} //si serve di una lista ausiliaria che viene riempita in maniera ordinata (rispetto al tempo) grazie alla funzione inserisci
        l->head = tmp.head;   //la head della lista ausiliaria viene sostituita con la head della lista originaria (ormai svuotata), ottenendo così tale lista ordinata come richiesto
    }
}


void set_ordinata_position (lista_t * l) {  //funzione analoga a set_ordinata_time che utilizza invece position
    lista_t tmp;
    if(l->ord == POSITION);
    else {
        l->ord = POSITION;
        while(l->head != NULL) {inserisci(l->head,&(*tmp.head));}
        l->head = tmp.head;
    }
}


void free_lista (lista_t **pl) { //libera la lista
    elem_t *tmp; //si utilizza un puntatore ad un elem_t temporaneo che progressivamente scorre la lista e viene messo a NULL
    elem_t*p;
    p=(**pl).head;
    while(p!=NULL){tmp=p->next;
        free(p);
        p=tmp;}
    free(*pl);
    (*pl)=NULL;}   //infine viene posta a NULL anche la head


int compute_theta (elem_t* pi, elem_t* pj, double* pth) {  //calcola il valore di theta
    double t_i, t_j, p_i, p_j, Th, tot;
    t_i = pi->time;   //qui i valori di un elem_t vengono assegnati a vari double così da permettere i calcoli necessari
    t_j = pj->time;
    p_i = pi->position;
    p_j = pj->position;
    tot = (V*(t_i - t_j))/(p_i - p_j); //questa formula si ottiene invertendo la formula data e utilizza la macro V=velocità della luce
    Th = asin(tot);  //attraverso la funzione asin di math.h si calcola l'arcoseno del valore spora ottenuto
    Th = Th*RAD2DEG;   //si converte quanto ottenuto da radianti in gradi
    return 0;
   // if ((pi->time)==NULL || (pj->time)==NULL || (pi->position)==NULL || (pj->position)==NULL) return -1;   //condizione di errore, nel caso pi o pj sia vuoto (MOMENTANEAMENTE MESSO COME COMMENTO CAUSA ERRORE!)
}

elem_t* leggi_registrazione_2 (FILE* f){   //questa funzione è simile a leggi_registrazione, ma serve per il calcolo della media
    elem_t* p;
    double x, y; //lo scopo di questa funzione è di ottenere un puntatore ad un elem_t che però contenga solo i valori di theta, momentaneamente associati al valore della posizione
    flag_t k;
    if( f==NULL ) {
        perror("Errore in apertura del file");
    }
    
    fscanf(f, "%lf %lf %d", &x, &y, &k);
    if(p==NULL) return NULL;
    else{
        p->position = x;
        p->time = 0;  //la differenza sostanziale è che questa volta i campi di time e flag vengono inizializzati a 0 così da avere valori solo in position (i valori di theta)
        p->flag = 0;
        p->next = NULL;}
    return p;
}

double media (FILE * f, double* pm) {
    elem_t* p;lista_t l;
    double sum=0,media;
    int nelem;
    inserisci(&l,p);   //si inserisce in una lista i valori degli elem_t ottenuti
    while(p!=NULL) {leggi_registrazione_2 (f);
        sum += p->position;  //alla variabile sum viene associato il valore che all'interno della lista è associato al campo position
        media = sum/nelem;} //calcola la media dividendo la sommatoria ottenuta per il numero di elementi della lista
    return media;  //restituisce il valore della media
}


double deviazione (FILE * f, double* ps, double m)   //calocla la deviazione standard
{   double tmp, devstd, p,med;
    int i;
    int nelem;
    fscanf(f,"%lf",&tmp);
    med=media(f,&p);
    for(i=0;i<nelem;i++){   //cicla per un numero di volte pari al numero di elelmenti della lista
        devstd=((tmp-med)*(tmp-med));}
    devstd=devstd/(nelem-1);
    return devstd;} //restituisce il valore atteso della deviazione




/** path file registrazioni */
#define FILE1 "/Users/ruggicus/Desktop/file-c/rag.c/rag.c/RAGGICOSMICI/DATA/data1.txt"

/** lunghezza buffer */
#define N 2048

int main (void) {
    /* conterrà il file delle registrazioni */
    FILE* f;
    /* punterà alla lista creata leggendo il file */
    lista_t * ll;
    /* temporaneo per memorizzare l'elemento letto prima di inserirlo in lista */
    elem_t* pelem;
    /* per le segnalazioni di errore */
    int err;
    /* per eliminare i commenti */
    char buf[N+2];
    
    
    /* Test 0 */
    fprintf(stdout,"Test 0: \n");
    
    /* Test creazione, stampa e deallocazione lista vuota */
    ll = new_lista();
    
    stampa_lista(stdout,ll) ;
    free_lista(&ll);
    if ( ll != NULL ) return EXIT_FAILURE;
    
    /* Test 1 */
    fprintf(stdout,"Test 1: \n");
    
    /* apro il file dati in lettura */
    f = fopen (FILE1,"r");
    if ( f == NULL ) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    
    /* eliminiamo la prima linea di commento */
    if ( fgets(buf,N+2,f) == NULL ) exit(EXIT_FAILURE);
    if (buf[0] != '#') exit(EXIT_FAILURE);
    
    /* leggiamo le registrazioni ed inseriamole in una nuova lista */
    ll = new_lista();
    
    while ( ( pelem = leggi_registrazione(f) ) != NULL ) {
        /* inseriamo nella lista in ordine di lettura */
        err = inserisci (ll,pelem);
        if ( err == -1 ) return EXIT_FAILURE;
    }
    /* stampa del risultato */
    stampa_lista(stdout,ll) ;
    
    
    /* deallochiamo la lista */
    free_lista(&ll);
    if ( ll != NULL ) return EXIT_FAILURE;
    
    fclose(f);
    
    return EXIT_SUCCESS;
    
}
 

rodhellas

Utente Èlite
1,522
427
CPU
Ryzen 5 3600
Dissipatore
GELID Phantom
Scheda Madre
MSI B450 Gaming Plus Max
HDD
500GB m.2 + 2TB HDD
RAM
16GB Corsair LPX 3000mhz
GPU
Gigabyte GTX 960 OC
Audio
Integrata
Monitor
SyncMaster 223BW
PSU
Antec HCG-520M
Case
Meshify C
Net
Gigabit Fastweb
OS
Windows 10 64bit
Codice:
lista_t * new_lista ( void ) {
    
    lista_t * l ;
    
    
    if ( (  l = malloc (sizeof ( lista_t ) ) ) == NULL ) {
        return NULL;
    }
    
    l->head = NULL ;
    l->ord = NOTORD;
    return l;
}
Io sono abituato a mettere la dicitura struct prima di chiamare una struttura. Comunque: nell'if dovresti mettere (struct lista_t*)malloc(bla bla) perchè sennò la malloc ti fa solo un cast a void (e non a struttura). Secondo, quando la allochi di solito la malloc ritorna sempre null, quindi l'if è sempre rispettato e ritorna sempre NULL.
Per creare una lista vuota dovresti fare cosi:
Codice:
struct list_t *new_list(){ //mi crea la prima lista vuota (NULL)


    struct list_t *list = (struct list_t*) malloc(sizeof(struct list_t));
    struct node_t *node = (struct node_t*) malloc(sizeof(struct node_t));
    list->head = node;
    node = NULL;
    return list;
    
}
I le strutture sono chiamate con nomi diversi. Cosi ti crea la lista (ovvero la tua testa) e la fa puntare al primo nodo (NULL).
Per la stampa, fai prima a farne solo una con (elem_t *h) come parametro. Nel main ci passi l->head e dopo la fai ricorsiva. Se l->head == NULL, ritorni nulla (o al massimo scrivi che la lista è vuota), se diverso da NULL fai i tuoi calcoli e ci passi h->next.
Comunque ti conviene inserire i valori uno dietro all'altro e poi ordinarli in base all'occorrenza. Poi mi pare di vedere che per aggiungere un nodo fai un casino di funzioni inutili (tipo void insert(elem_t **p, elem_t *el). Per aggiungere un nodo in una funzione, chiami la funzione e ci passi la testa ( l->head ), crei una struttura di supporto, fai struct elem_t *temp = l->head (o quello che gli passi), la fai scorrere finchè temp->next == NULL. Allochi un nuovo nodo, ci metti dentro i valori, la fai puntare a NULL e fai puntare temp->next (cioè la tua coda) al nuovo nodo. Tutto in una funzione.
 
  • Mi piace
Reazioni: roger21

roger21

Nuovo Utente
21
3
Codice:
lista_t * new_lista ( void ) {
    
    lista_t * l ;
    
    
    if ( (  l = malloc (sizeof ( lista_t ) ) ) == NULL ) {
        return NULL;
    }
    
    l->head = NULL ;
    l->ord = NOTORD;
    return l;
}
Io sono abituato a mettere la dicitura struct prima di chiamare una struttura. Comunque: nell'if dovresti mettere (struct lista_t*)malloc(bla bla) perchè sennò la malloc ti fa solo un cast a void (e non a struttura). Secondo, quando la allochi di solito la malloc ritorna sempre null, quindi l'if è sempre rispettato e ritorna sempre NULL.
Per creare una lista vuota dovresti fare cosi:
Codice:
struct list_t *new_list(){ //mi crea la prima lista vuota (NULL)


    struct list_t *list = (struct list_t*) malloc(sizeof(struct list_t));
    struct node_t *node = (struct node_t*) malloc(sizeof(struct node_t));
    list->head = node;
    node = NULL;
    return list;
    
}
I le strutture sono chiamate con nomi diversi. Cosi ti crea la lista (ovvero la tua testa) e la fa puntare al primo nodo (NULL).
Per la stampa, fai prima a farne solo una con (elem_t *h) come parametro. Nel main ci passi l->head e dopo la fai ricorsiva. Se l->head == NULL, ritorni nulla (o al massimo scrivi che la lista è vuota), se diverso da NULL fai i tuoi calcoli e ci passi h->next.
Comunque ti conviene inserire i valori uno dietro all'altro e poi ordinarli in base all'occorrenza. Poi mi pare di vedere che per aggiungere un nodo fai un casino di funzioni inutili (tipo void insert(elem_t **p, elem_t *el). Per aggiungere un nodo in una funzione, chiami la funzione e ci passi la testa ( l->head ), crei una struttura di supporto, fai struct elem_t *temp = l->head (o quello che gli passi), la fai scorrere finchè temp->next == NULL. Allochi un nuovo nodo, ci metti dentro i valori, la fai puntare a NULL e fai puntare temp->next (cioè la tua coda) al nuovo nodo. Tutto in una funzione.

ti ringrazio ma mi sono accorto adesso di aver omesso che la funzione per creare la nuova lista non compare perchè è data,non è quello il problema purtroppo
 

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili