Function help to delete repeated values contained in a double-chained C List

Asked

Viewed 668 times

1

I’m not able to develop a function within my code that removes duplicate values within a doubly chained list, could help me?

Follow the code done so far, the function I need to fix is the retiraValor:

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

typedef struct lista {
float valor;
struct lista* anterior;
struct lista* proximo;
} Lista;

/* Criar uma lista vazia */
Lista* criarLista(){
return NULL;
}

/* Insere no inicio da lista*/
Lista* inserirNaLista(Lista* list, float valor){
Lista* novo = (Lista*) malloc(sizeof(Lista));
novo->valor = valor;

if (!list){
    novo->anterior = NULL;
    novo->proximo = NULL;
}
else {
    novo->anterior = NULL;
    novo->proximo = list;
    list->anterior=novo;
}

return novo;
}

/* Imprime na tela os valores*/
void imprimirLista(Lista* lista){
Lista* proximaLista;
for (proximaLista=lista; proximaLista!=NULL; proximaLista = proximaLista->proximo){
    printf("\nO valor da lista e: %.2f", proximaLista->valor);
 }
}

/* Busca um determinado valor na pilha*/
Lista* buscarNo(Lista* list, float valor){
Lista* proximaLista;
for(proximaLista = list; proximaLista != NULL; proximaLista = proximaLista->proximo){
    if (proximaLista->valor == valor){
        return proximaLista;
      }
   }
 }


Lista* retornaTopo(Lista* list){
Lista* temp = list->anterior;
if (temp->anterior != NULL){
    return retornaTopo(temp);
}
else{
    return temp;
  }
}



/* Retira um nó conforme o valor informado*/
Lista* retirarNo(Lista* list, float valor){
/*Ponteiro para o n? anterior*/
Lista* anteriorLista;
anteriorLista = criarLista();

/*Ponteiro para percorrer a lista*/ 
Lista* proximaLista;
proximaLista = criarLista();

proximaLista = list;
while (proximaLista != NULL && proximaLista->valor != valor){
    anteriorLista = proximaLista;
    proximaLista = proximaLista->proximo;
}

// Nao achamos o valor
if (proximaLista == NULL){
    return list;
}

if (anteriorLista == NULL){
    list = proximaLista->proximo;
    proximaLista->proximo->anterior = NULL;
}
else{
    if (proximaLista->proximo == NULL){
        anteriorLista->proximo = NULL;
        if (anteriorLista->anterior != NULL){
            anteriorLista = retornaTopo(anteriorLista);
        }

        return anteriorLista;
    }
    else{
        anteriorLista->proximo = proximaLista->proximo;
        if (anteriorLista->anterior != NULL){
            anteriorLista = retornaTopo(anteriorLista);
        }

        return anteriorLista;
      }
  } 
}



//ESSA EH A FUNCAO QUE NAO ESTOU CONSEGUINDO DESENVOLVER
void retiraValor(Lista* lista){
Lista* proximaLista;
float numero = proximaLista->valor;
for(proximaLista = lista; proximaLista != NULL; proximaLista = proximaLista->proximo){
    if (proximaLista->valor == numero){
        retirarNo(proximaLista, numero);
    }
  }

}


int main(int argc, char *argv[]) {
Lista *lista;
lista = criarLista();

Lista *lista2;
lista2 = lista;

lista = inserirNaLista(lista, 6);
lista = inserirNaLista(lista, 10);
lista = inserirNaLista(lista, 7.25);
lista = inserirNaLista(lista, 5);
lista = inserirNaLista(lista, 10);
lista = inserirNaLista(lista, 23);
imprimirLista(lista);
printf("\n\n");

Lista* retira_n(lista2);
imprimirLista(lista2);


  return 0;
}

2 answers

1

Your remove functionValue() is only taking the first value from the list and checking if it is duplicated. If the intention is to remove all duplicates, it is necessary to iterate between all the values of the list and, for each of them, check if there is another in the rest of the list with the same value.

Another thing is that the takenNo() is too complicated... In theory, it should only receive a node, remove it from the list by updating the pointers and release its memory (with a free(), that was missing from your code).

  • 1

    Emoon, thank you so much for the tips, I’m going to work on that, thank you.

1


I took a look at your algorithm and made some modifications:

void retiraValor(Lista* lista) {
    Lista* minhalista = lista;
    while (minhalista != NULL) {
        Lista* innerList = lista;
        int equal = 0;
        while (innerList != NULL) {
            if (innerList->valor == minhalista->valor) {
                equal++;
            }
            if (equal == 2) {
                retirarNo(lista, minhalista->valor);
                break;
            }
            innerList = innerList->proximo;
        }
        minhalista = minhalista->proximo;
    }
}

His approach was somewhat vague, the process of removing duplicate items on a disorderly double-chained list is quite costly. In the algorithm basically for each item in the list, I went through the list again looking for more than one occurrence of the same value and used its function take back to get you off the list.

I tested with the function main in this way:

int main(int argc, char *argv[]) {
    Lista *lista;
    lista = criarLista();

    Lista *lista2;
    lista2 = lista;

    lista = inserirNaLista(lista, 6);
    lista = inserirNaLista(lista, 10);
    lista = inserirNaLista(lista, 7.25);
    lista = inserirNaLista(lista, 5);
    lista = inserirNaLista(lista, 10);
    lista = inserirNaLista(lista, 23);

    imprimirLista(lista);
    printf("\n");

    retiraValor(lista);

    imprimirLista(lista);

  return 0;
}

I hope it helps!

  • Felipe Nascimento, You are the guy, I thank you so much for your help and cooperation, solved my problem in its entirety, I’m still learning about chained lists, I’m a little difficult, but I tested tirelessly solve alone before asking for help. Thank you very much, stay with God.

Browser other questions tagged

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