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

1

I am not able to develop a function inside my code that removes the duplicate values within a double-chained list, could you help me?

Here is the code I have done so far, the function I need to fix is 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;
}
    
asked by anonymous 04.11.2016 / 08:23

2 answers

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 a bit vague, the process of removing duplicate items in a double-chained chained list is quite costly. In the algorithm basically for each item in the list, I ran the list again looking for more than one occurrence of the same value and used its removeNo function to get it out of the list.

I tried the main function 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!

    
04.11.2016 / 14:21
1

Its function removesValue () is only getting 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 in the list and, for each one of them, check if there are others in the rest of the list with the same value.

Another thing is that retreatNo () is too complicated ... In theory, it should just get a node, remove it from the list by updating the pointers and free its memory (with a free , which was missing in your code).

    
04.11.2016 / 14:05