How to sort a struct within a struct

1

I want to do sorting of a struct that is referenced inside another struct:

Detail: can be sorted using selection sort

typedef struct{
    int tipo;
    char dispositivo[50];
    int prioridade;
}Perif;

typedef struct no{
    Perif info;
    struct no* prox;
}Aux_Perif;

Aux_Perif* criarLista(){
    return NULL;
}

void imprimirLista(Aux_Perif** lista, int size){
    Aux_Perif* aux = *lista;
    while (aux != NULL){
    std::cout << "DISPOSITIVO: ";
    std::cout << aux->info.dispositivo << std::endl;
    std::cout << "PRIORIDADE: ";
    std::cout << aux->info.prioridade << std::endl;
    aux = aux->prox;
    }
}

void inserirFinal(Aux_Perif** perifericos, Perif barramento){
    Aux_Perif* novo = (Aux_Perif*)new Aux_Perif;
    novo->info = barramento;
    Aux_Perif* aux = *perifericos;
    Aux_Perif* anterior = NULL;
    if (*perifericos == NULL){
        *perifericos = novo;
    }else{
        while(aux != NULL){
            anterior = aux;
            aux = aux->prox;
        }
    anterior->prox = novo;
    }

}

int main(){
int solic;
int cont = 0;
int aux = 0, prior = 0;
Aux_Perif* perifericos;
perifericos = criarLista();
std::cout << "Entre com o número de solicitações: " << std::endl;
std::cin >> solic;
std::cout << "Periféricos:\n1. Impressora\n2. Mouse\n3. Teclado\n4. Scanner\n5. Roteador\n6. Disco Rígido" << std::endl;
std::cout << "De acordo com os números e Periféricos acima, insira a ordem de entrada das solicitações e sua prioridade" << std::endl;
while (cont < solic){
    Perif ordem;
    std::cin >> aux >> prior;
    switch (aux){
        case 1:
            //ordem.dispositivo = 'Impressora';
            strcpy(ordem.dispositivo, "Impressora");
            break;
        case 2: 
            strcpy(ordem.dispositivo , "Mouse") ;
            break;
        case 3: 
            strcpy(ordem.dispositivo , "Teclado");
            break;
        case 4:
            strcpy(ordem.dispositivo , "Scanner");
            break;
        case 5:
            strcpy(ordem.dispositivo , "Roteador");
            break;
        case 6: 
            strcpy(ordem.dispositivo , "Disco Rígido");
            break;
        default:
            std::cout << "Error" << std::endl;
            break;
    }

    ordem.tipo = aux;
    ordem.prioridade = prior;
    cont++;
    inserirFinal(&perifericos, ordem);
    //delete[] ordem;

}
std::cout << "Daisy Chaining utilizando método de ordem a chegada ou entrada." << std::endl;
imprimirLista(&perifericos, solic);
std::cout << "Método por Prioridade: " << std::endl;
imprimirLista(&perifericos, solic);
return 0;
}

In this case, I want to sort by Aux_perif -> info -> prioridade . Help, guys!

    
asked by anonymous 06.06.2016 / 08:48

1 answer

-1

You can do this:

void selectionsort_AuxPerif(Aux_Perif **vetor, int tamanho) {
    int i, j;
    for (i = 0; i < tamanho - 1; i++) {
        int menor = i;
        for (j = i + 1; j < tamanho; j++) {
            if (vetor[menor]->info->prioridade > vetor[j]->info->prioridade) menor = j;
        }
        if (menor != i) {
            Aux_Perif *temp = vetor[menor];
            vetor[menor] = vetor[i];
            vetor[i] = temp;
        }
    }
}

void ordena_AuxPerif(Aux_Perif **perif) {
    // 1. Se a lista está vazia, então nem faz nada.
    if (perif == NULL) return;

    // 2. Descobre o tamanho da lista.
    int tamanho = 0;
    Aux_Perif *v;
    for (v = *perif; v != NULL; v = v->prox) {
        tamanho++;
    }

    // 3. Monta um vetor com os elementos da lista.
    Aux_Perif **vetor = (Aux_Perif **) malloc(sizeof(Aux_Perif *) * tamanho);
    int i = 0
    for (v = *perif; v != NULL; v = v->prox, i++) {
        vetor[i] = v;
    }

    // 4. Ordena o vetor.
    selectionsort_AuxPerif(vetor, tamanho);

    // 5. Corrige os ponteiros de acordo com a nova ordenação.
    for (i = 0; i < tamanho - 1; i++) {
        vetor[i]->prox = vetor[i + 1];
    }
    vetor[i]->prox = NULL;

    // 6. Corrige o ponteiro para o início da lista.
    *perif = vetor[0];

    // 7. Deleta o vetor auxiliar.
    free(vetor);
}

Ah, another detail I saw in your code is that the imprimirLista function never uses the size parameter. You can remove this parameter if you prefer.

In addition, if you want to replace the sort method with some other, just change the call to the function selectionsort_AuxPerif by someone else who has the parameters of the same type. For example:

void mergesort_AuxPerif(Aux_Perif **vetor, int tamanho) {
    if (tamanho <= 1) return;
    int meio = tamanho / 2;
    mergesort_AuxPerif(vetor, meio);
    mergesort_AuxPerif(&(vetor[meio]), tamanho - meio);

    Aux_Perif **temp = (Aux_Perif **) malloc(tamanho * sizeof(Aux_Perif *));
    int i, a = 0, b = meio;
    for (i = 0; i < tamanho; i++) {
        if (b == tamanho || (a < meio && vetor[a]->info->prioridade < vetor[b]->info->prioridade)) {
            temp[i] = vetor[a];
            a++;
        } else {
            temp[i] = vetor[b];
            b++;
        }
    }
    for (i = 0; i < tamanho; i++) {
        vetor[i] = temp[i];
    }
    free(temp);
}
    
06.06.2016 / 13:36