Ir ao conteúdo
  • Cadastre-se

C Ordenação em lista encadeada


Igor Vargas

Posts recomendados

Olá estou com duvida em como ordenar com strcmp. Minha funcão cadastra o aluno também ordema.Mas quando cadastro digamos "Barbara" ele fica na frente de "Ana", ele da um erro, onde ele para de funcionar

 

int CadastroAluno(Cad* li){
	printf("voce SELECIONOU CADASTRAR ALUNO\n\n");
	struct elementoCadastro *no =(struct elementoCadastro*)malloc(sizeof(struct elementoCadastro));
	
	struct Cadastro c;
	printf("Nome:");
	fflush(stdin);
	gets(c.nome);
	printf("Nascimento:");
	gets(c.nascimento);
	printf("Endereco:");
	gets(c.endereco);
	printf("Estado:");
	gets(c.estado);
	printf("Cidade:");
	gets(c.cidade);
	printf("Email:");
	gets(c.email);
	printf("CPF:");
	scanf("%d",&c.cpf);
	printf("Telefone:");
	scanf("%d",&c.telefone);
	c.matricula = matricula;
	int igual =AlunoIgual(li,c);
	char testando[50]; 
	if(igual == 1){
		printf("**Esse cpf ja existe**!\n");	
	}else{	
				
		
		//int testando = procura(li,c.nome);

		
		if(*li==NULL){
			no->cadastro = c;
			no->prox = (*li);
			no->ant = NULL;
			if(*li!=NULL){
			(*li)->ant = no;
			
		}
		*li = no;				
		}else{
			struct elementoCadastro *atual,*ant,*o = *li;
			printf("Entrou aqui");
		while(o!=NULL){
			if(strcmp(o->cadastro.nome,c.nome) < 0){
				ant = o;
				return 1;

			}else{
				//no->ant = o;
				no->cadastro = c;
				no->prox = (*li);
				*li= no;
					
			}if(ant->prox == NULL){
				printf("Entrou no print");
				no->cadastro = c;
				o->prox = no;
				no->ant = o->prox;
				
				*li = no;
			}
			o = o->prox;
			
		}
	
	
		
	}
		
			
		}
		
		
		
			
		matricula++;
	printf("Aluno cadastrado com sucesso Matricula -> %d\n\n",no->cadastro.matricula);
	}

 

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

falta um laço de repetição para comparar sempre o nome "atual", com o próximo, até onde o vetor está preenchido(com a variavel soma). 

Exemplo, você tem 3 registros apenas dentro do vetor, os laços de repetição irão de 0 até 3, e não até o final total

da sua capacidade(100). E uma maneira de otimizar seu código e deixá-lo mais leve.

para dar um exemplo, com um cadastro bem simples só de nomes: 

Citação

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

struct dados {
   char  nome[30];
};

   int  main() {      
            
      dados vet[100];
      int op=0,soma=0,i,j;
      char temp[30];
                   
while(op!=3){
                  
      printf("\n==============MENU==================\n");            
      printf("1-Cadastrar Pessoa: \n");                    
      printf("2-Ordenar por Nome: \n");      
      printf("3-Sair\n\n\n");
      scanf("%d",&op);
     
      if(op==1){ 
      printf("informe nome:");
      fflush(stdin);   
      fgets(vet[soma].nome,30,stdin);
      fflush(stdin);                
      soma ++;
      system("cls");}
         
            
    if(op==2){
    printf("=================================\n");
    printf("Ordenando por nome");       
              
    //ordena
     for(i = 1; i < soma; i++){
         for (j = 0; j < soma-1; j++){
                       
              if(strcmp(vet[j].nome,vet[j+1].nome) > 0){
                strcpy(temp,vet[j].nome);
                 strcpy(vet[j].nome,vet[j+1].nome);
                 strcpy(vet[j+1].nome,temp);}                               
           }      
         }
                      
     //imprime                   
      for(i=0;i<soma;i++){ 
      printf("\n");   
      printf("nome = %s\n",vet.nome);}}
                     
    if(op==3){
    printf("Encerrando Programa...\n");
    system("pause");        
    exit(0);} 

  }// fim while
}// fim main
 

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Olá!

 

Ajude o pessoal a ajudar você e poste o programa completo ou um link para ele. Não deve ser muito grande afinal

Não posso olhar tudo agora, mas posso dar uns palpites e um brinde. Quando e se você postar o programa e se ainda precisar de ajuda eu olho de novo.

 

Os palpites

  • Não misture as coisas: Ler os valores e digitar a estrutura completa vai fazer você perder uma enormidade de tempo pra testar seu programa. Computadores são muito bons em recortar e colar coisas então faça o programa aos poucos.
    Imagine sua lista por exemplo: Vai cadastrar os alunos a partir de um ou outro campo, tipo o CPF ou o nome e eventualmente o o nome e o CPF caso tenha caras com o mesmo nome. Então cadastre inicialmente só esses campos chave na estrutura. Quando estiver funcionando você inclui o resto na função de leitura

 

  • Crie uns valores direto no programa usando algo como
struct Cadastro c1, c2, c3, c4;

char *nome1 = "Igor";
char *cpf1 = "123.456.789.01";

char *nome2 = "Vargas";
char *cpf2 = "123.456.789.02";

char *nome3 = "Clube";
char *cpf3 = "123.456.789.03";

char *nome4 = "Hardware";
char *cpf4 = "123.456.789.04";

strcpy( c1.nome, nome1 );
strcpy( c1.cpf, cpf1);

strcpy( c2.nome, nome2 );
strcpy( c1.cpf, cpf2);

strcpy( c3.nome, nome3 );
strcpy( c3.cpf, cpf3);

strcpy( c4.nome, nome4 );
strcpy( c4.cpf, cpf4);
  • Usando valores conhecidos e diferentes mas quase iguais para poder usar recortar e colar
  • Teste sua  lista mudando a ordem de inserção: teste inserir no ínício, no fim e no meio, inserir todos já na ordem e inserir todos ao contrário. Com 4 elementos já dá pra testar tudo.
  • Antes de tudo crie a função que lista os valores do cadastro. Não perca tempo. 
  • Você precisa testar os encadeamentos nos dois sentidos então faça sua função lista()  mostrar os caras usando o ponteiro prox até NULL e aí liste usando o ponteiro pra tras ant até NULL e você testa de uma vez se está construindo certo a estrutura.

E o brinde?

 

Seria legal se você tivesse uma função que criasse um aluno do jeito que você precisa, mas numerando

os alunos a partir de "Aluno-0000" e

os CPF a partir de "123.456.700.00" em diante e a cada chamada ela fosse aumentando os últimos números até, sei lá, 9999

Assim você poderia testar com 0 até 10.000 alunos na sua lista à vontade sem ter nem que copiar e colar. Ou pior, digitar na entrada do programa. Para 15 alunos por exemplo criaria assim:

Nome: [Aluno-0000] CPF: [123.456.700-00]
Nome: [Aluno-0001] CPF: [123.456.700-01]
Nome: [Aluno-0002] CPF: [123.456.700-02]
Nome: [Aluno-0003] CPF: [123.456.700-03]
Nome: [Aluno-0004] CPF: [123.456.700-04]
Nome: [Aluno-0005] CPF: [123.456.700-05]
Nome: [Aluno-0006] CPF: [123.456.700-06]
Nome: [Aluno-0007] CPF: [123.456.700-07]
Nome: [Aluno-0008] CPF: [123.456.700-08]
Nome: [Aluno-0009] CPF: [123.456.700-09]
Nome: [Aluno-0010] CPF: [123.456.700-10]
Nome: [Aluno-0011] CPF: [123.456.700-11]
Nome: [Aluno-0012] CPF: [123.456.700-12]
Nome: [Aluno-0013] CPF: [123.456.700-13]
Nome: [Aluno-0014] CPF: [123.456.700-14]

Um programa de teste de 10 linhas para uma hipotética função le_aluno()

int main()
{
    Aluno* aluno_lido = NULL;
    for (int i = 0; i < 15; ++i)
    {
        aluno_lido = le_aluno();
        printf("Nome: [%s] CPF: [%s]\n", aluno_lido->nome, aluno_lido->cpf);
        free(aluno_lido);
    }    // end for
    return 0;
}

E uma função le_aluno()? Veja uma: a cada vez que você chama ela cria um aluno novinho e devolve o endereço dele e aí você pode inserir na sua lista. E quando estiver certo você troca essa rotina por outra que lê mesmo os caras da entrada padrão...
 

static Aluno* le_aluno()
{
    // essa rotina pode salvar horas: a cada vez que e chamada
    // devolve o endereço de um aluno bem comportado com nome a partir de
    // "Aluno-0000" e CPF "123.456.7XY- ZT" 
    // limitando o teste a 'apenas' 10.000 alunos 
    // so que não precisa ler nenhum
    static int        quantos = -1;
    char*            pref_nome = "Aluno-";
    char*            pref_CPF = "123.456.7";
    char            valor[50];

    quantos++;
    int X = quantos / 1000;    
    int Y = (quantos % 1000) / 100;    
    int Z = (quantos % 100)/ 10;    
    int T = quantos % 10;
    // monta o nome do aluno
    Aluno* pAluno = (Aluno*)malloc(sizeof(Aluno));
    if(pAluno == NULL) return NULL;
    sprintf(valor, "%s%d%d%d%d", pref_nome, X, Y, Z, T);
    strcpy(pAluno->nome, valor);
    sprintf(valor, "%s%1d%1d-%1d%1d", pref_CPF, X, Y, Z, T);
    strcpy(pAluno->cpf, valor);
    return pAluno;
}    // end le_akuno()

Claro que tem maneiras menos preguiçosas de escrever isso :) mas já é tarde. Não tem nada de especial na rotina, exceto talvez a variável quantos declarada como static para não perder o valor entre cada chamada. e as chamadas a sprintf() para formatar os valores sem esquentar a cabeça com índices e tal...

Obviamente você pode usar essa rotina e criar a estrutura inteira preenchida usando a mesma técnica, e mesmo depois ir lendo os valores aos poucos e usando os gerados por ela pra ganhar mais um tempo...

 

Boa sorte aí com o trabalho

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...