Removing specific element from a double-linked list

Asked

Viewed 406 times

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 arrived in which it relates 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’s 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;
}
}

1 answer

0


The problem lies in the logic of what is in for And it’s mostly about the fact that you’re removing based on cartas that represents the beginning and not the knot that goes walking in the for. You should also consider for the potential of the current node he called aux to be NULL and end if it happens.

Focusing on these points the 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 I changed the:

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

Because it’s wrong and it was creating an unnecessary additional knot that wasn’t going to be used, and it was still causing a memory leak because it didn’t have the free correspondent.

Unfortunately, although the logic is correct it will still not work in your code because the pointers ant are not being properly constructed, which is now their next step. Debug the code against the functions that insert nodes and observe the various pointers ant that you’re building and realizing the point where you’re not assigning them correctly in order to fix it and get it all working.

  • I get it. Thanks for helping me!

Browser other questions tagged

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