#Hnry# 0 Denunciar post Postado Novembro 12, 2007 Boa noite pessoal, estou com um problema nesse código, o que ele precisa fazer é o seguinte: recebe uma fila encadeada e exclui os elementos repetidos, não posso utilizar uma fila auxiliar e nem ordená-la. Este é o meu código até agora, ele está com um erro que não acho, depois da leitura dos valores ele "tranca" e mostra só o primeiro elemento da fila, era para primeiramente mostrar a fila inicial e depois mostrar a fila com os elementos excluidos. Se alguém tiver a possibilidade de me dar uma ajuda agradeço. Valeu!! #include <stdio.h> #include <conio.h> #include <malloc.h> struct nodo { int valor; struct nodo *prox; }; void enfilera(struct nodo **inicio, struct nodo **fim, int v) { struct nodo *aux, *p; aux = (struct nodo*) malloc (sizeof(struct nodo)); if (aux!=NULL) { aux->valor=v; aux->prox=NULL; if (*inicio==NULL) { *inicio=aux; } else { (*fim)->prox=aux; } *fim=p; } } void desenfilera (struct nodo **inicio, struct nodo **fim, int *valor) { struct nodo *aux; if (*inicio == NULL) printf("FILA VAZIA"); else if ((*inicio)->prox== NULL) { *valor = (*inicio)->valor; free(*inicio); *inicio=NULL; *fim=NULL; } else { *valor=(*inicio)->valor; aux=*inicio; *inicio=(*inicio)->prox; free(aux); } } void exclui_repetidos(struct nodo **inicio, struct nodo **fim) { struct nodo *aux, *aux2, *fimp; int v; aux=*inicio; fimp=*fim; aux = *inicio; while(aux != fimp) { aux2 =aux->prox; while(aux2 != NULL){ if(aux->valor == aux2-> valor)//isso quer dizer que tem alguem repetido. desenfilera (inicio, fim, &v);// CHAMA FUNÇÃO DESENFILERA... aux2 = aux2->prox; } aux = aux->prox; } } /* =============================================== */ /* Procedimento para mostrar o conteudo da FILA. */ /* =============================================== */ void mostra_fila (struct nodo *fila ) { struct nodo *aux; aux=fila; while (aux != NULL) /* Enquanto nao for final da lista... */ { printf("Valores-> %d\n",aux->valor); aux=aux->prox; } } /* Programa principal */ int main() { int val, test; struct nodo *ini=NULL, *fi=NULL; printf("\nPara encerrar a insercao digite 0 !"); do { printf("\nInforme um valor. : "); scanf("%i",&val); if (val != 0) { enfilera(&ini, &fi, val); if (test == 0) printf("\nErro de alocacao de memoria..."); } } while (val != 0); getch(); printf("Exclui...\n"); getch(); mostra_fila(ini); exclui_repetidos(&ini, &fi); getch(); printf("\n\n"); mostra_fila(ini); getch(); } Compartilhar este post Link para o post Compartilhar em outros sites
Kandrade 7 Denunciar post Postado Novembro 13, 2007 Vamos discutir sobre seu código e resolver os problemas. Primeiro, voce consegue achar todos os elementos repetidos? Voce testou? Essa chamada: desenfilera (inicio, fim, &v) Não há necessidades de v ser passado por referencia e o valor que deve ser passado para ser removido é o repetido, então voce teria que passar um desses dois: aux->valor ou aux2-> valor Sugestão mude o protótipo da função para: void desenfilera (struct nodo **inicio, struct nodo **fim, int valor) Depois disso vamos resolver o que falta. http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif Compartilhar este post Link para o post Compartilhar em outros sites
#Hnry# 0 Denunciar post Postado Novembro 17, 2007 Fiz as alterações que voce falou! e tambem mudei algumas coisa no Enfilera e funcionou... Mas temos outro problema... Quando eu coloco uma sequencia de numero, por exemplo 1,2,3,4,5,1,2,3 o resultado depois de passar pelo exclui_repetidos deveria ser 1,2,3,4,5, mas esta aparecendo 4,5,1,2,3.... Ou seja tenho que excuir o segundo que se repete e esta excluindo o 1º... o que posso alterar para modificar isso? #include <stdio.h> #include <conio.h> #include <malloc.h> struct nodo { int valor; struct nodo *prox; }; void enfilera(struct nodo **inicio, struct nodo **fim, int v) { struct nodo *aux,*p; aux = (struct nodo *) malloc (sizeof(struct nodo)); if (aux != NULL) { aux->valor=v; aux->prox=NULL; if (*inicio == NULL) { *inicio = aux; *fim = aux; } else { p=*inicio; while (p->prox != NULL) p=p->prox; p->prox=aux; *fim=aux; } } } void desenfilera (struct nodo **inicio, struct nodo **fim, int *valor) { struct nodo *aux; if (*inicio == NULL) printf("FILA VAZIA"); else if ((*inicio)->prox == NULL) { *valor = (*inicio)->valor; free(*inicio); *inicio=NULL; *fim=NULL; } else { *valor=(*inicio)->valor; aux=*inicio; *inicio=(*inicio)->prox; free(aux); } } void exclui_repetidos(struct nodo **inicio, struct nodo **fim) { struct nodo *aux, *aux2, *fimp; int v; aux=*inicio; fimp=*fim; aux = *inicio; while(aux != fimp) { aux2 =aux->prox; while(aux2 != NULL){ if(aux2->valor == aux-> valor){//isso quer dizer que tem alguem repetido. desenfilera (inicio, fim, &aux->valor);// CHAMA FUNÇÃO DESENFILERA... } aux2 = aux2->prox; } aux = aux->prox; } } void mostra_fila (struct nodo *fila ) { struct nodo *aux; aux=fila; //printf("passou 1\n"); while (aux != NULL) /* Enquanto nao for final da lista... */ { // printf("passou 2\n"); printf("Valores-> %d\n",aux->valor); aux=aux->prox; } // printf("passou 3\n"); } /* Programa principal */ int main() { int val, test; struct nodo *ini=NULL, *fi=NULL; printf("\nPara encerrar a insercao digite 0 !"); do { printf("\nInforme um valor. : "); scanf("%i",&val); if (val != 0) { enfilera(&ini, &fi, val); if (test == 0) printf("\nErro de alocacao de memoria..."); } } while (val != 0); getch(); printf("Exclui...\n"); getch(); // printf("passou A\n"); mostra_fila(ini); // printf("passou B\n"); exclui_repetidos(&ini, &fi); getch(); printf("\n\n"); mostra_fila(ini); getch(); } Compartilhar este post Link para o post Compartilhar em outros sites
Kandrade 7 Denunciar post Postado Novembro 18, 2007 O problema está na funcão desinfilera. Ela entra nesse último else e retira o elemento. else { *valor=(*inicio)->valor; // copia o primeiro valor aux=*inicio; // auxiliar recebe o endereco do primeiro elemento da fila *inicio=(*inicio)->prox; // vai para o proximo free(aux); // deleta o primeiro elemento } Voce precisa procurar pelo valor. Algo do tipo: while (p->valor == valor) p=p->prox; Voce encontrará o elemento a ser retirado, ai é só refazer a conexão da fila. Compartilhar este post Link para o post Compartilhar em outros sites
#Hnry# 0 Denunciar post Postado Novembro 18, 2007 O problema está na funcão desinfilera. Ela entra nesse último else e retira o elemento. else { *valor=(*inicio)->valor; // copia o primeiro valor aux=*inicio; // auxiliar recebe o endereco do primeiro elemento da fila *inicio=(*inicio)->prox; // vai para o proximo free(aux); // deleta o primeiro elemento } Voce precisa procurar pelo valor. Algo do tipo: while (p->valor == valor) p=p->prox; Voce encontrará o elemento a ser retirado, ai é só refazer a conexão da fila. A sugestão seria SUBSTITUIR o else por While? e o"p" passo por referencia no desinfilera, para fazer o teste? Compartilhar este post Link para o post Compartilhar em outros sites
Kandrade 7 Denunciar post Postado Novembro 18, 2007 o while pode ficar dentro do else e p seria a referencia do primeiro elemento da fila. A sugestão seria SUBSTITUIR o else por While? e o"p" passo por referencia no desinfilera, para fazer o teste? Compartilhar este post Link para o post Compartilhar em outros sites
#Hnry# 0 Denunciar post Postado Novembro 18, 2007 o while pode ficar dentro do else e p seria a referencia do primeiro elemento da fila. A sugestão seria SUBSTITUIR o else por While? e o"p" passo por referencia no desinfilera, para fazer o teste? Bah mas... eu compararia se o primeiro elemento, ou seja o que eu vou remover é igual ao demais. Correto? Mas em que parte do codigo isso ocorre? Teria como você explicar direto no codigo? Meu cérebro ta fritado... Compartilhar este post Link para o post Compartilhar em outros sites
Kandrade 7 Denunciar post Postado Novembro 19, 2007 Veja, suponho que sua funcão que chama a desinfilera esteja correta, ou seja, ela faz a chamada da funcão passando a referencia para a fila e o valor do elemento a ser removido. Agora vamos analisar a funcão desenfilera. void desenfilera (struct nodo **inicio, struct nodo **fim, int *valor) { struct nodo *aux; if (*inicio == NULL) // se a referencia eh nula, entao nao ha elementos na fila printf("FILA VAZIA"); else if ((*inicio)->prox == NULL) // senao, se o proximo elemento é nulo, entao so tem um elemento { *valor = (*inicio)->valor; free(*inicio); *inicio=NULL; *fim=NULL; } else // se entrar aqui quer dizer que tem mais de 1 elemento na fila { // implemente o que te falei aqui // faca o while, mas não modifique diretamente a referencia de *inicio // voce pode usar: aux = *inicio e incrementar o aux: aux = aux -> prox } } Seguinte use as dicas que te passei. A idéia é como se fosse a pesquisa: voce vai procurar pela ocorrencia de um valor que foi passado por paramentro. Quando encontrar esse valor voce terá que fazer: Elemento anterior aponta para aux -> prox, isso é se ele nao for nem o primeiro e nem o ultimo da fila. Para esses dois tem um tratamento diferente. Tente fazer isso que te falei. Compartilhar este post Link para o post Compartilhar em outros sites