Visualizzazione dei risultati da 1 a 3 su 3
  1. #1

    [C] Eliminazione in mezzo ad una lista

    Salve ragazzi,
    ho un altro problema con le liste.
    Questa volta, si tratta dell'eliminazione di un nodo che si trova in mezzo ad una lista dinamica.

    Il problema si pone solo quando voglio eliminare un elemento della lista che non sia il secondo (o il primo, ma quello ha un elimina "a parte" visto che devo eliminare in testa).
    Per esempio, se io voglio eliminare il terzo elemento della lista, il programma mi elimina sì il terzo, ma mi elimina anche l'elemento in testa.

    Se io ho una lista formata da:

    2
    3
    4
    5

    e voglio eliminare 2 o 3, il programma funziona correttamente. Ma se io voglio eliminare 4, la lista che mi ritorna è:

    3
    5

    eliminando così anche l'elemento in testa alla lista.

    Il codice sorgente del programma è:

    codice:
    //elimina un elemento inserito dall'utente
    
    #include <stdio.h>
    #include <iostream>
    
    typedef int E;
    struct blocchetto;
    typedef blocchetto*L;
    typedef struct blocchetto{
    E elem;
    L next;};
    
    L insert(E e,L l){
    L q;  
    q=(L)malloc(sizeof(blocchetto));
    q->elem=e;
    q->next=l;
    return(q);} 
    
    void stampa(L l){
    L temp=l;
    while(temp!=NULL){
    printf("Elemento: %d \n",temp->elem);
    temp=temp->next;}}
    
    L eliminaelemento(L l){
    int elemento;
    L cnc;
    printf("Quale elemento vuoi eliminare?\n");
    scanf("%d",&elemento);
    if(l->elem==elemento){
    L tmp=l;
    l=l->next;
    free(tmp);
    return(l);}
    while(l->next!=NULL){
    if(l->next->elem==elemento){
    cnc=l->next;
    l->next=l->next->next;
    free(cnc);
    return(l);}
    l=l->next;}}
    
    
    int main(){
    E e; L l;
    l=NULL;
    char risp[3];
    while(strcmp(risp,"no")!=0){
    printf("Vuoi inserire un elemento?(si o no) \n");
    scanf("%s",&risp);
    if(strcmp(risp,"si")==0){
    printf("Inserisci elemento: \n");
    scanf("%d",&e);
    l=insert(e,l);}}
    
    stampa(l);
    
    l=eliminaelemento(l);
    printf("NUOVA LISTA:\n");
    stampa(l);
    
    
    
    
    
    free(l);
    
    system("PAUSE");
    return(0);}
    Il sorgente l'ho postato tutto per completezza, ma bisogna ovviamente focalizzarsi sulla funzione eliminaelemento.

    Potreste aiutarmi a trovare l'errore?

    Grazie mille in anticipo.

  2. #2
    Utente di HTML.it L'avatar di infinitejustice
    Registrato dal
    Nov 2001
    residenza
    Barcelona
    Messaggi
    772
    Il problema è che in eliminaelemento() ti muovi lungo la lista utilizzando l'unico puntatore che hai alla testa delle lista e poi lo restituisci, perdendo pezzi.

    All'inizio della funzione creati un secondo puntatore temporaneo che userai per scorrere la lista e fare le tue operazioni.


    L eliminaelemento(L l){
    int elemento;
    L cnc;
    L temp = l;
    printf("Quale elemento vuoi eliminare?\n");
    scanf("%d",&elemento);
    if(temp->elem==elemento){
    L tmp=temp;
    temp=temp->next;
    free(tmp);
    return(temp);
    }
    while(temp->next!=NULL){
    if(temp->next->elem==elemento){
    cnc=temp->next;
    temp->next=temp->next->next;
    free(cnc);
    return(l);
    }
    temp=temp->next;
    }
    }


    cj@cj:~/projects/gdb$ gcc -c html.it.c
    html.it.c: In function ‘main’:
    html.it.c:58: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[3]’
    cj@cj:~/projects/gdb$ gcc -lm html.it.o
    cj@cj:~/projects/gdb$ ./a.out
    Vuoi inserire un elemento?(si o no)
    si
    Inserisci elemento:
    5
    Vuoi inserire un elemento?(si o no)
    si
    Inserisci elemento:
    4
    Vuoi inserire un elemento?(si o no)
    si
    Inserisci elemento:
    3
    Vuoi inserire un elemento?(si o no)
    si
    Inserisci elemento:
    2
    Vuoi inserire un elemento?(si o no)
    no
    Elemento: 2
    Elemento: 3
    Elemento: 4
    Elemento: 5
    Quale elemento vuoi eliminare?
    4
    NUOVA LISTA:
    Elemento: 2
    Elemento: 3
    Elemento: 5
    sh: PAUSE: not found


    Quando lavori con puntatori a liste, fai sempre attenzione a non perder mai la testa della lista. O lavora con una lista doppia (ciascun elemento ha un puntatore a next ed uno a prev. first->prev = NULL; last->next = NULL): in questo caso puoi recuperare la testa in qualunque momento.
    Live fast. Troll hard.
    Pythonist | Djangonaut | Puppeteer | DevOps | OpenStacker | Lost in malloc
    Team Lead @Gameloft Barcelona

  3. #3
    Grazie mille, gentilissimo, era proprio quello l'errore.
    Adesso funziona, grazie!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.