Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

#Hnry#

em fila encadeada

Recommended Posts

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

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

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

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

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

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

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

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

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.