Printing the double-chained list in reverse order

0

Good morning, this is my first post here on Stack Overflow. I was trying to make a double-chained list print in reverse order. However, after going through this list in reverse, it produced the result unexpectedly. My code is printing more than necessary. Here is the attached print and source code.

I count on your help!

#include<stdio.h>#include<stdlib.h>//Exercício:Inserircélulasnalistaduplamenteencadeadaeemseguidaimprimí-lasnaordeminversatypedefstructcel{structcel*ant;intconteudo;structcel*prox;}celula;celula*criaLista(){returnNULL;}celula*insereInicioLista(celula*inicio,intvalor){celula*novo=(celula*)malloc(sizeof(celula));//InicialmenteosponteirosiniefimapontamparaNULLcelula*ini=inicio;celula*fim=inicio;if(novo==NULL){printf("Memoria insuficiente\n");
        exit(1);

    } else if(verificaListaVazia(inicio)){

        novo->conteudo = valor;
        novo->prox = fim;
        novo->ant = ini;

        fim = novo;
        ini = novo;

        return ini;

    } else {

        novo->conteudo = valor;
        novo->prox = fim;
        fim->ant = novo;
        ini = novo;

        return ini;
    }
}

int verificaListaVazia(celula* lista){
    return lista == NULL;
}


void imprimeLista(celula* lista){

    celula* p = lista;

    for(; p != NULL; p = p->prox){
        printf("%d-> ", p->conteudo);
//      printf("valor: %d\n", p->conteudo);
//      printf("Endereco de p: %p\n", p);
//      printf("Endereco do prox de p: %p\n", p->prox);
//      printf("Endereco anterior a p: %p\n\n", p->ant);
    }

    printf("\n\n");
}

void imprimeListaNaOrdemInversa(celula* inicio){

    celula* p = inicio; //Ponteiro que aponta para o início da lista

    while(p->prox != NULL){
        p = p->prox;
    }

    //Ao final, p passa a apontar para o último nó
    celula* final = p;

    for(; final != NULL; final = final->ant){
        printf(" <- %d", final->conteudo);
    }

    printf("\n\n");
}

int main(int argc, char *argv[]) {

    celula* lista = (celula*)malloc(sizeof(celula));

    if(lista == NULL){
        printf("Memoria insuficiente\n");
        exit(1);

    } else {

        lista = criaLista();

        lista = insereInicioLista(lista, 10);
        lista = insereInicioLista(lista, 20);
        lista = insereInicioLista(lista, 30);
        lista = insereInicioLista(lista, 40);
        lista = insereInicioLista(lista, 50);

        printf("LISTA DUPLAMENTE ENCADEADA\n");
        imprimeLista(lista);

        printf("LISTA DUPLAMENTE ENCADEADA INVERSA\n");
        imprimeListaNaOrdemInversa(lista);
    }

    return 0;
}
    
asked by anonymous 02.09.2017 / 17:00

1 answer

0

The problem is only in the insereInicioLista function that has some incorrect things.

The fim pointer is not necessary since it is always inserting at startup, and if it were, it would be necessary to scroll through the list so that it points to the right node.

The main point that fails is not to be assigned novo->ant in else , here:

else {

    novo->conteudo = valor;
    novo->prox = fim;
    fim->ant = novo;
    ini = novo;

    return ini;
}

What causes it to be undefined, and that the navigation goes through the memory outside, accessing random addresses. This should be NULL , as it was in the if part.

There are also some simplifications to the code that can be made, for example, in the returns:

    ini = novo;

    return ini;

} else {

    ...
    ini = novo;

    return ini;
}

Here we see that the value to be returned is always novo , so it will be easier to return directly novo and out if because it is the same in both cases.

Correcting and simplifying the function insereInicioLista looks like this:

celula* insereInicioLista(celula* inicio, int valor){

    celula* novo = (celula*)malloc(sizeof(celula));

    //testa logo se conseguiu obter memoria, antes de fazer mais coisas como tinha antes
    if(novo == NULL){ 
        printf("Memoria insuficiente\n");
        exit(1);
    }

    //a construção dos ponteiros do novo não depende se a lista está vazia, logo 
    //pode ser feita fora do if
    novo->conteudo = valor; 
    novo->prox = inicio;
    novo->ant = NULL;

    if (!verificaListaVazia(inicio)){ //ou if (inicio != NULL) que era mais simples
       inicio->ant = novo; //se existe lista colocar o ant do primeiro a apontar para o novo
    }

    return novo;
}

I also want to mention that the createList function that has:

celula* criaLista(){
    return NULL;
}

It does not make much sense because it always returns NULL . It would be simpler and clearer to change your initialization to% w /% of

lista = NULL;
    
02.09.2017 / 21:05