Ordination by name and enrollment

0

I have this list simply chained and I do not know how to order it. I need to sort by name and enrollment.

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

void BuscarMatricula();
void Inserir();
void Exibir();
void Remover();
int menu();
void OrdenaNome();


typedef struct registro 
{
    char nome[50];
    int matricula;
    float nota;
    struct registro *prox;
}Registro;


int menu()
{
    int op;
    printf("\n\tLista Encadeada Simples-\n");
    printf("Informe a opção desejada\n");
    printf("1 - Inserir\n");
    printf("2 - Buscar pro Matricula\n");
    printf("3 - Remover\n");
    printf("4 - Ordenar por nome\n");
    printf("5 - Ordenar por Matricula\n");
    printf("6 - Exibir os elementos da Lista\n");
    printf("7 - Calcular média da turma\n");
    scanf("%d", &op);
    return op;
}



void Inserir(Registro *inicio)
{
    Registro *novo;
    novo=inicio;
    if(novo->prox==NULL) // Alocação comúm;
    { 
        novo->prox=(Registro *)malloc(sizeof(Registro));
        novo = novo->prox;
    printf("Informe o nome do aluno\n");
    scanf("%s",novo->nome);
    __fpurge(stdin);

    printf("Informe a Matricula do Aluno\n");
    scanf("%d", &novo->matricula);

    printf("Informe a nota do Aluno\n");
    scanf("%f", &novo->nota);
    novo->prox = NULL;

    }
    else // novo apontando para uma posição já alocada;
    {
        novo=novo->prox;
        Inserir(novo);
    }

}

void Exibir(Registro *inicio)
{
    Registro *Exibir;
    Exibir=inicio->prox;
    if(Exibir==NULL)
    {
        printf("\t-------------------------------------------------\n");
        printf("\tRegistro Vazio\n");
        printf("\t-------------------------------------------------\n");
    }
    else{
    do{
        printf("\t Nome do Aluno: %s | Matricula :%d | Nota: %.2f \n", Exibir->nome,Exibir->matricula,Exibir->nota );
        printf("\t-------------------------------------------------\n");
        Exibir=Exibir->prox;
    }while(Exibir!=NULL);
    }
}

void BuscarMatricula(Registro *inicio)
{
    int Pesquisar_matricula;
    Registro *Buscar;
    Buscar=inicio->prox;
    if(Buscar==NULL)
        {
        printf("\t-------------------------------------------------\n");
        printf("\tRegistro Vazio\n");
        printf("\t-------------------------------------------------\n");
    }
    else{
    printf("Informe a matricula do aluno\n");
    scanf("%d", &Pesquisar_matricula);
    do{
        if(Pesquisar_matricula==Buscar->matricula)
        {
            printf("\t Nome do Aluno: %s | Matricula :%d | Nota: %.2f \n", Buscar->nome,Buscar->matricula,Buscar->nota );
            break;
        }
        else
            Buscar=Buscar->prox;
        if(Buscar==NULL)
            printf("Matricula não encontrada\n");
    }while(Buscar!=NULL);
    }
}

void Remover(Registro *inicio)
{
    int Pesquisar_matricula;
    Registro *Remover;
    Registro *anterior;
    Remover=inicio->prox;
    anterior=inicio;
    if(Remover==NULL)
        {
        printf("\t-------------------------------------------------\n");
        printf("\tRegistro Vazio\n");
        printf("\t-------------------------------------------------\n");
    }
    else{
    printf("Informe a matricula do aluno\n");
    scanf("%d", &Pesquisar_matricula);
    do{
        if(Pesquisar_matricula==Remover->matricula)
        {
            printf("\t Aluno removido: %s | Matricula :%d | Nota: %.2f \n", Remover->nome,Remover->matricula,Remover->nota );
            anterior->prox=Remover->prox;
            free(Remover);
            break;
        }
        else
            Remover=Remover->prox;
            anterior=anterior->prox;
        if(Remover==NULL)
            printf("Matricula não encontrada\n");
    }while(Remover!=NULL);
    }
}

void OrdenaMatricula(Registro *inicio)
{
    int ss;
    Registro *Ordenar;
    Ordenar=inicio->prox;
    Registro *aux;



    while(Ordenar!=NULL)
    {
        aux=Ordenar->prox;
        while(aux!=NULL)
        {
            if(aux->matricula<Ordenar->matricula)
            {   
                ss=Ordenar->matricula;
                Ordenar->matricula=aux->matricula;
                aux->matricula=ss;
            }
        }   
        Ordenar=Ordenar->prox;
        aux=aux->prox;
    }

}





int main()
{ 
    Registro *inicio;
    inicio=(Registro *)malloc(sizeof(Registro));  
    inicio->prox=NULL;


    int op;
    int sair=0;
    int posvalida;
    while(!sair)
    {
        op=menu();
        switch(op)
        {
            case 1:{
                Inserir(inicio);
                break;

            }
            case 2:{
                BuscarMatricula(inicio);
                break;
            }
            case 3:{
                Remover(inicio);
                break;
            }
            case 5:{
                OrdenaMatricula(inicio);
                break;
            }
            case 6:{
                Exibir(inicio);
                break;
            }
            case 7:{
                sair=1;
                break;
            }
        }

    }

}
    
asked by anonymous 04.11.2017 / 03:16

1 answer

1

The OrdenaMatricula function was very close to running. Only the aux in the while pointer increment has been increased and you have not used nome and nota .

You can change it to:

void OrdenaMatricula(Registro *inicio) {
    int ss;
    char nometemp[50]; //variavel adicionada para o swap
    float notatemp; //variavel adicionada para o swap

    Registro *Ordenar;
    Ordenar=inicio->prox;
    Registro *aux;

    while(Ordenar!=NULL) {
        aux=Ordenar->prox;

        while(aux!=NULL) {
            if(aux->matricula<Ordenar->matricula) {
                //agora troca os 3 campos de dados de cada vez
                ss=Ordenar->matricula;
                strcpy(nometemp,Ordenar->nome);
                notatemp = Ordenar->nota;

                Ordenar->matricula=aux->matricula;
                strcpy(Ordenar->nome, aux->nome);
                Ordenar->nota = aux->nota;

                aux->matricula=ss;
                strcpy(aux->nome, nometemp);
                aux->nota = notatemp;
            }
            aux=aux->prox; //aux tem de navegar para o da frente aqui
        }
        //em vez de aqui, que era onde estava 
        Ordenar=Ordenar->prox;
    }   
}

See the Ideone example

The ordering by nome is exactly the same by changing only the if of the second while . Instead of repeating the entire function to sort by name you can try to reuse the whole logic once it is the same.

There are several ways to do this. I show one that uses pointers to functions so that you can pass a function of comparing records. To begin, change the OrdenaMatricula function to make it receive a comparison function and make if based on this function:

void Ordena(Registro *inicio, int *compara(Registro*,Registro*) ) {
    //--------------------------------^ função de comparação aqui
    ...

    while(Ordenar!=NULL) {
        aux=Ordenar->prox;
        while(aux!=NULL) {
            if(compara(aux, Ordenar) > 0) {
            //---^ comparação é feita agora chamando a função recebida com os 2 registros
                ...
            }
            aux=aux->prox;
        }
        Ordenar=Ordenar->prox;
    }
}

Notice that in this last step I changed the function name to Ordena since it will serve the two sorts. I also assumed that the comparison function returns an integer with >0 value for greater, <0 for less and 0 for equal, in the style of strcmp .

The comparison function for the enrollments would look like this:

int comparaMatriculas(Registro *r1, Registro *r2){
    return (r1->matricula - r2->matricula);
}

And in% with% of the call to main you must now include this last function:

case 5: {
    Ordena(inicio, comparaMatriculas /*<--aqui*/);
    break;
}

For name comparison you just need to create a function that compares names in which you can directly base on Ordena of strcmp

int comparaNomes(Registro *r1, Registro *r2){
    return strcmp(r1->nome, r2->nome);
}

And make the corresponding call in <string.h> :

case 4: {
    Ordena(inicio, comparaNomes );
    break;
}

Additional Notes

To try to fit in with the algorithm and logic of the question I did not change the way the ordering itself was being done. There are, however, more efficient ways of sorting, even though they are considerably more complex.

You can:

  • Change the algorithm to a more efficient one such as Merge Sort , which already guarantees complexity in the order of O (n log n).
  • Do not change the elements of the list by copying their values, but by moving only the pointers.
04.11.2017 / 04:19