Problem removing at the beginning in a doubly chained list

Asked

Viewed 214 times

3

Hello. When I try to use the "remove" function to remove the first element from the list, apparently nothing happens. But, soon after using the function removes and try to insert a new node in the list, it does not insert, and the second time I try to insert, it returns to insert normally as if nothing had happened. I’m breaking my head with this, and I can’t find the problem of why not remove and presents this "error" when inserting after trying to remove.

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

struct cliente{
    int senha;
    char prio;
    struct cliente *ant,*prox;
};
typedef struct cliente Cliente;

void insere_inicio(Cliente *cabeca);
void listar(Cliente *cabeca);
void libera_lista(Cliente *cabeca);
void retira(Cliente *cabeca);

int main(){

    Cliente *cabeca=(Cliente *) malloc(sizeof(Cliente));
    cabeca->prox = NULL;
    cabeca->ant = NULL;

     int q; /* Caractere para receber a opcao do usuario */
     do {
     printf("\n\nOpcoes:\
     \n1 -> para inserir no inicio o cliente;\
     \n2 -> para listar todas as senhas;\
     \n3 -> para retirar o primeiro da lista;\
     \n0 -> para sair \n:");
     fflush(stdin);
     scanf("%i", &q); /* Le a opcao do usuario */
     switch(q) {
     case 1: insere_inicio(cabeca); break;
     case 2: listar(cabeca); break;
     case 3: retira(cabeca); break;
     case 0: break;
     default: printf("\n\n Opcao nao valida");
     }
     fflush(stdin); /* Limpa o buffer de entrada */
     } while ((q != 0) );
     libera_lista(cabeca);
}

//função para alocar espaço de memoria e criar o nó
/**/
Cliente *aloca(){
    //tenta alocar um novo nó
    Cliente *novono=(Cliente *) malloc(sizeof(Cliente));
    if(!novono){//se não alocou, e portanto novo não existe faça
        printf("Sem memoria disponivel!\n");
        exit(1);
    }else{
         printf("senha: ");
         fflush(stdin);
         scanf("%i", &novono->senha); 
         printf("\nprioridade: [P] para preferencial ou [N] normal: ");
         fflush(stdin);
         scanf("%c", &novono->prio);
         fflush(stdin);
         //q = novono->prio;
         return novono;
    }
}

void insere_inicio(Cliente *cabeca) {

 Cliente *novono=aloca();
 Cliente *aux = cabeca->prox;
 cabeca->prox = novono;
 novono->prox = aux;
 novono->ant = NULL;
}

void listar(Cliente *cabeca){

    if(cabeca->prox == NULL){
        printf("\nTem nada aqui nao hein\n");
        return;
    }   
    Cliente *aux;
    aux = cabeca->prox;
    while(aux != NULL){

        printf("\n\n-------------------------------");
        printf("\nSenha: %i", aux->senha);
        printf("\nPrioridade: %c", aux->prio);
        aux=aux->prox;  
    }
}

void retira(Cliente *cabeca){

    if(cabeca->prox == NULL){
        printf("lista esta vazia");
    }else{
        Cliente *aux;
        aux = cabeca;
        cabeca = cabeca->prox;
    //  cabeca->ant = NULL; 
        free(aux);
    }
}

void libera_lista(Cliente *cabeca){
    //se a lista nao estiver vazia
    if(cabeca->prox != NULL){
        /**/
        Cliente *aux;
        aux = cabeca->prox;
        while(cabeca != NULL){
            aux = cabeca;
            cabeca = cabeca->prox;
            free(aux);

        }

        free(cabeca);

    }
}

1 answer

1


The problem lies there:

void retira(Cliente *cabeca){

if(cabeca->prox == NULL){
    printf("lista esta vazia");
}else{
    Cliente *aux;
    aux = cabeca;
    cabeca = cabeca->prox;
//  cabeca->ant = NULL; 
    free(aux);
  }
}

Two errors are found here.

1st The pointer aux starts to point to the variable head, and should point to the element after the head, which in theory is the first element of the list.

2nd The instructioncabeca = cabeca->prox; does not delete the first element from the list, in fact it makes the pointer cabeca point to where it was already pointing. The right thing is to do cabeca point to the next of its next, who in theory would be the second element, which will become the first

With the correct corrections the function will be like this:

 void retira(Cliente *cabeca){
     if(cabeca->prox == NULL){
       printf("lista esta vazia");
    }else{
      Cliente *aux;
      aux = cabeca->prox;
      cabeca->prox = cabeca->prox->prox;

      if(cabeca->prox != NULL){
        cabeca->prox->ant = cabeca;
      }

      aux->ant = NULL;
      aux->prox = NULL;
      free(aux);
   }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.