Removing specific element from a double-linked list

0

I created a function to remove a specific element from a list. However, the code only works right when it comes to the first element. The logic is that when the element arrives in which it concerns it takes the previous / next and clears the specific element of memory.

Here is the function:

void remove_posicao(lista *cartas)
{
lista *aux = (lista *) malloc(sizeof(lista));
int i, pos;

aux = cartas -> prox;

if(!cartas)
{
    printf("Impossível alocar memória");
    exit(1);
}

printf("Digite a posição que queira deletar: ");
scanf("%d", &pos);

for(i = 1; i <= pos; i++)
{
    if (i == pos)
    {
        cartas -> prox = aux -> prox;
        cartas -> ant = aux -> ant;
        free(aux);
    }
    else
    {
        aux = aux -> prox;
    }
}
}

Here is the rest of the code:

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

struct No
{
int valor;
struct No *prox;
struct No *ant;
};

typedef struct No lista;

void inicializa(lista *cartas)
{
cartas -> prox = NULL;
cartas -> ant = NULL;
printf("Lista de cartas inicializadas\n\n");
}

void adiciona_inicio(lista *cartas)
{
lista *novo = (lista *) malloc(sizeof(lista));
if(!cartas)
{
    printf("Impossível alocar memória");
    exit(1);
}
printf("Digite uma carta para inserir no inicio: ");
scanf("%d", &novo -> valor);
lista *aux = cartas -> prox;
cartas -> prox = novo;
novo -> prox = aux;
novo -> ant = cartas;

if(aux != NULL)
{
    aux -> ant = novo;
}

}

void adiciona_fim(lista *cartas)
{
lista *novo = (lista *) malloc(sizeof(lista));

if(!cartas)
{
    printf("Impossível alocar memória");
    exit(1);
}
printf("Digite uma carta para ser alocada no fim: ");
scanf("%d", &novo -> valor);
novo -> prox = NULL;

if(checa_lista(cartas))
{
    cartas -> prox = novo;
    novo -> ant = cartas;
}
else
{
    lista *aux = cartas -> prox;
    while(aux -> prox != NULL)
    {
        aux = aux -> prox;
        aux -> prox = novo;
        novo -> ant = aux;
    }
}
}

void adiciona_posicao(lista *cartas)
{
lista *aux = (lista *) malloc(sizeof(lista));
lista *novo = (lista *) malloc(sizeof(lista));
int i, pos;

aux = cartas -> prox;

if(!cartas)
{
    printf("Impossível alocar memória");
    exit(1);
}

printf("Digite o valor que quer armazenar: ");
scanf("%d", &novo -> valor);
printf("Digite a posição que queira posicionar: ");
scanf("%d", &pos);

for(i = 1; i <= pos; i++)
{
    if (i == pos)
    {
        novo -> prox = aux;
        novo -> ant = aux->ant;
        aux -> ant -> prox = novo;


    }
    else
    {
        aux = aux->prox;
    }
}
}

void remove_inicio(lista *cartas)
{
lista *aux = cartas -> prox -> prox;
lista *head = cartas -> prox;
printf("Removendo o primeiro elemento do baralho \n");
cartas -> prox = cartas -> prox -> prox;
aux -> ant = cartas;
free(head);
}

void remove_posicao(lista *cartas)
{
lista *aux = (lista *) malloc(sizeof(lista));
int i, pos;

aux = cartas -> prox;

if(!cartas)
{
    printf("Impossível alocar memória");
    exit(1);
}

printf("Digite a posição que queira deletar: ");
scanf("%d", &pos);

for(i = 1; i <= pos; i++)
{
    if (i == pos)
    {
        cartas -> prox = aux -> prox;
        cartas -> ant = aux -> ant;
        free(aux);
    }
    else
    {
        aux = aux -> prox;
    }
}
}

void remove_fim(lista *cartas)
{
while(cartas -> prox -> prox != NULL)
{
    cartas = cartas -> prox;
}
free(cartas -> prox);
cartas -> prox = NULL;
printf("Removendo o último elemento do baralho! \n");
}

void limpa_lista(lista *cartas)
{
if(!checa_lista(cartas))
{
    lista *aux, *atual, *head;
    head = cartas;
    atual = cartas -> prox;
    while(atual -> prox != NULL)
    {
        aux = atual -> prox;
        free(atual);
        atual = aux;

    }
    if(atual -> prox == NULL)
    {
        head -> prox = NULL;
        free(atual);
    }
}
}

void mostra_lista(lista *cartas)
{
if(checa_lista(cartas))
{
    printf("Lista vazia\n");
    return ;
}
lista *aux = cartas -> prox;
while(aux != NULL)
{
    printf("Cartas = %d\n", aux -> valor);
    aux = aux -> prox;
}
}

void mostra_anterior(lista *cartas)
{
if(checa_lista(cartas))
{
    printf("Lista vazia\n");
    exit(1);
}

lista *aux = cartas;
printf("Cartas ");
while(aux -> prox != NULL)
{
    aux = aux -> prox;
    printf("-> %d", aux -> valor);
}
printf(" - ");

while(aux -> ant != NULL)
{
    printf("%d ->", aux -> valor);
    aux = aux -> ant;
}
printf("\n");
}

int checa_lista(lista *cartas)
 {
  if(cartas -> prox == NULL)
{
    return 1;
}
else
{
    return 0;
}
}

int tamanho_lista(lista *cartas)
{
int i = 0;
while(cartas -> prox != NULL)
{
    cartas = cartas -> prox;
    i++;
}
return i;

}

main()
{
setlocale(LC_ALL,"portuguese");
lista *cartas = (lista *) malloc(sizeof(lista));
int i;

if(!cartas)
{
    printf("Impossível alocar memória");
    exit(1);
}
else
{
    i = checa_lista(cartas);
    if(i == 1)
    {
        printf("Lista vazia\n");
    }
    else if (i == 0)
    {
        printf("Lista não vazia\n");
    }

    printf("Memória alocada\n");

    inicializa(cartas);
    adiciona_fim(cartas);
    adiciona_inicio(cartas);
    mostra_lista(cartas);
    mostra_anterior(cartas);
    adiciona_posicao(cartas);
    mostra_lista(cartas);
    remove_posicao(cartas);
    mostra_lista(cartas);
    /*remove_inicio(cartas);
    remove_fim(cartas);
    limpa_lista(cartas);*/
    i = tamanho_lista(cartas);
    free(cartas);
    return 0;
}
}
    
asked by anonymous 02.10.2018 / 22:34

1 answer

0

The problem is in the logic of what it has in for and has mostly to do with removing it based on the cartas that represents the start and not the node that is walking in for . In addition, you should also consider in for the potential of the current node that you called aux to be NULL and end if this happens.

Focusing on these points, remove_posicao would look like this:

void remove_posicao(lista *cartas) {
    lista *aux = cartas -> prox;
    int i, pos;

    if(!cartas) {
        printf("Impossível alocar memória");
        exit(1);
    }

    printf("Digite a posição que queira deletar: ");
    scanf("%d", &pos);

    for(i = 1; i <= pos && aux != NULL; i++) {
    //                       ^-- teste adicional para NULL
        if (i == pos) {
            lista *prox = aux -> prox; //captura primeiro o proximo do corrente
            aux -> prox -> ant = aux -> ant; // altera o anterior do próximo para o anterior
            aux -> ant -> prox = prox; //altera o proximo do anterior para o proximo
            free(aux); //remove o corrente
            aux = prox; //e avança para o próximo que tinha sido guardado no inicio
        } else {
            aux = aux -> prox;
        }
    }
}

Notice that I also changed the:

lista *aux = (lista *) malloc(sizeof(lista));
aux = cartas -> prox;

Because it was wrong and was creating an unnecessary additional node that was not going to be used, and still caused a memory leak because it did not have the corresponding free .

Unfortunately, although the logic is still not working in your code because the ant pointers are not being properly constructed, that is now your next step. Debug the code for the functions that insert nodes and note the various ant pointers you are building and note the point where you are not assigning them correctly in order to fix it and get everything up and running.

    
03.10.2018 / 02:01