Remove elements from the end of a list in C

1

I have a problem where my list is removing all the elements and leaving only the last and penultimate.

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

typedef struct LISTA{

    int dado;
    struct LISTA *prox; 




}lista;


lista *insere(lista *p, int valor){

    lista *novo;
    novo=(lista*)malloc(sizeof(lista));
    novo->dado = valor;
    novo->prox = p;
    return novo;

}


void imprime(lista *p){
    lista *novo;
    for(p = novo; p!= NULL; p=p->prox){
        printf("%d",p->dado);

    }


}

/*lista *retira(lista *p, int valor){


    lista *aux = NULL;
    lista *novo = p;

    while(novo != NULL && novo->dado != valor){
    aux = novo;
    novo = novo->prox;  
    }
    if(novo == NULL){
        return p;
    }
    if(aux == NULL){
        novo = novo->prox;
    }else{
        aux->prox = novo->prox;
    }
    free(novo);
    return p;

}*/


lista *retiraFirst(lista *l){
    lista *tmp = l;
    tmp = l->prox;
    l->prox = tmp->prox;
    l->prox--;
    return tmp;


}


lista *retiraLast(lista *l){

    lista *ultimo = l,
    *penultimo = l;

    while(ultimo->prox != NULL){
        penultimo = ultimo;
        ultimo = ultimo->prox;

    }
    penultimo->prox = NULL;
    ultimo->prox= penultimo;
    return ultimo;



}






main(){

lista *l;
lista *primeiro, *ultimo;
    l = NULL;
    l = insere(l, 20);
    l = insere(l, 30);
    l = insere(l, 40);
    l = insere(l, 50);
    l = insere(l, 60);

    imprime(l);
    printf("----");
    //l =retira(l, 40);
    //l = retiraFirst(l);
    //imprime(l);
    printf("----");
    l = retiraLast(l);
    imprime(l);

}
    
asked by anonymous 27.08.2018 / 00:41

2 answers

2

First of all, the print function is bad, in the way you are doing it, it is working on the original list, ie, doing p=p->proximo progresses in the list, then loses the start of the list.

You should do this:

void imprime(lista *p){
    lista *novo=p;
    for(; novo!= NULL; novo=novo->prox){
        printf("%d  ",novo->dado);

    }
}

In the retiraLast function, the error is in l=retiraLast(l) should be ultimo = retiraLast(l); in main , since the function is well implemented.

The problem with this implementation is that it will not be able to give free to the last element, because if you want to go through the list and give free the last element will not be able to return to the beginning and so you should create in the struct a pointer to the start the list.

As for example like this:

typedef struct _l_elemento
{
    /* string armazenada */
    char* str;
    /* apontadores para elementos vizinhos */
    struct _l_elemento *proximo;
    struct _l_elemento *anterior;
} l_elemento;

typedef struct
{
    l_elemento *inicio;
    l_elemento *fim;
    int tamanho;
} lista;

I suggest to see some of my implementation of the list on GitHub >

    
27.08.2018 / 01:21
0

I suggest creating a struct to type "node" where it will store its data, and control the first and last within the struct list. And you should only create a list and pass it as a reference (via &) to your functions to ensure that you are editing the same list. See the code below:

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

typedef struct LISTA{
        struct no *pri;
        struct no *ult;
}lista;

struct no {
        int dado;
        struct no *prox;
};

void insere(lista *l, int valor);
void retira(lista *l, int valor);
void imprime(lista *l);

void imprime(lista *l){
        struct no *atual;
        atual = l->pri;
        while(atual != NULL){
                printf("%d\n", atual->dado);
                atual = atual->prox;
        }
}


void insere(lista *l, int valor){

        struct no *novo = malloc(sizeof(struct no));
        novo->dado = valor;
        novo->prox = NULL;

        /* primeiro item da lista
           pri == ult */
        if(l->pri == NULL) {
                l->pri = novo;
                l->ult = novo;
        }
        l->ult->prox = novo;
        l->ult = novo;
}

void retira(lista *l, int valor){
        struct no *atual, *achou = NULL;
        atual = l->pri;
        while(atual != NULL){
        /* se estiver no primeiro elemento */
                if(l->pri == atual &&
                        atual->prox->dado == valor){
                        achou = atual;
                        l->pri = achou->prox;
                        free(achou);
                        break;
                }else{                                                                                                                                                
                //olha uma posição na frente para não precisar voltar na lista                                                                                         
                   if(atual->prox != NULL && atual->prox->dado == valor){                                                                                                                  
                   // salva o proximo elemento                                                                                                                                         
                      achou = atual->prox;                                                                                                                                             
                   // atualiza o ponteiro do atual
                      atual->prox = achou->prox;
                    /* libera o elemento */                                                                                                                        
                      free(achou);                                                                                                                                                            
                      break;                                                                                                                                                           
                }

            }
                // avança o ponteiro
                atual = atual->prox;
        }

}


int main(){
        lista l;
        l.pri = NULL;
        l.ult = NULL;

        insere(&l, 10);
        insere(&l, 20);
        insere(&l, 30);
        insere(&l, 40);
        insere(&l, 50);
        insere(&l, 60);

        imprime(&l);
        printf("\n");

        retira(&l, 40);
        retira(&l, 50);
        imprime(&l);
}
    
27.08.2018 / 01:49