Existe alguma função de biblioteca disponível na biblioteca padrão C para fazer a classificação?
Existe alguma função de biblioteca disponível na biblioteca padrão C para fazer a classificação?
Respostas:
qsort()
é a função que você está procurando. Você o chama com um ponteiro para seu array de dados, o número de elementos nesse array, o tamanho de cada elemento e uma função de comparação.
Ele faz sua mágica e seu array é classificado no local. Segue um exemplo:
#include <stdio.h>
#include <stdlib.h>
int comp (const void * elem1, const void * elem2)
{
int f = *((int*)elem1);
int s = *((int*)elem2);
if (f > s) return 1;
if (f < s) return -1;
return 0;
}
int main(int argc, char* argv[])
{
int x[] = {4,5,2,3,1,0,9,8,6,7};
qsort (x, sizeof(x)/sizeof(*x), sizeof(*x), comp);
for (int i = 0 ; i < 10 ; i++)
printf ("%d ", x[i]);
return 0;
}
return (f > s) - (f < s);
qsort
função" Ponto 4 "Se dois elementos são comparados como iguais, sua ordem na matriz classificada resultante não é especificada."
A biblioteca padrão C / C ++ <stdlib.h>
contém qsort
funções.
Esta não é a melhor implementação de classificação rápida do mundo, mas é rápida e MUITO FÁCIL de ser usada ... a sintaxe formal do qsort é:
qsort(<arrayname>,<size>,sizeof(<elementsize>),compare_function);
A única coisa que você precisa implementar é compare_function, que recebe dois argumentos do tipo "const void", que podem ser convertidos para a estrutura de dados apropriada e, em seguida, retorna um destes três valores:
1. Comparando uma lista de inteiros :
simplesmente fundido a e b para se inteiros x < y
, x-y
é negativo, x == y
, x-y = 0
, x > y
, x-y
é positiva
x-y
é uma forma de atalho para fazê-lo :) reverter *x - *y
para *y - *x
por ordem decrescente / ordem inversa
int compare_function(const void *a,const void *b) {
int *x = (int *) a;
int *y = (int *) b;
return *x - *y;
}
2. Comparando uma lista de strings :
Para comparar strings, você precisa de uma strcmp
função dentro de <string.h>
lib.
strcmp
irá, por padrão, retornar -ve, 0, ve apropriadamente ... para classificar na ordem reversa, apenas inverta o sinal retornado por strcmp
#include <string.h>
int compare_function(const void *a,const void *b) {
return (strcmp((char *)a,(char *)b));
}
3. Comparando números de ponto flutuante :
int compare_function(const void *a,const void *b) {
double *x = (double *) a;
double *y = (double *) b;
// return *x - *y; // this is WRONG...
if (*x < *y) return -1;
else if (*x > *y) return 1; return 0;
}
4. Comparando registros com base em uma chave :
Às vezes você precisa classificar coisas mais complexas, como o registro. Aqui está a maneira mais simples de fazer isso usando a qsort
biblioteca.
typedef struct {
int key;
double value;
} the_record;
int compare_function(const void *a,const void *b) {
the_record *x = (the_record *) a;
the_record *y = (the_record *) b;
return x->key - y->key;
}
int
, os valores passados para o comparador são int *
disfarçados como void *
. Ao classificar uma matriz de char *
, portanto, os valores passados para o comparador são char **
disfarçados como void *
. Portanto, o código correto deve ser: int compare_function(const void *a,const void *b) { return (strcmp(*(char **)a, *(char **)b)); }
.
if (x > y) return +1; else if (x < y) return -1; else return 0;
, ou se você quiser uma expressão simples, então return (x > y) - (x < y);
. Isso sempre avalia duas comparações no nível C, mas o otimizador pode ser capaz de evitar isso. A subtração não funciona em valores sem sinal. A primeira versão funciona bem quando você está lidando com uma série de comparação - comparando 2 membros inteiros de uma estrutura primeiro, e se eles forem iguais, então dois duplos, depois duas strings, etc. Há mais de uma maneira de fazer isso, em C, bem como em Perl.
Com certeza: qsort()
é uma implementação de um tipo (não necessariamente quicksort como seu nome pode sugerir).
Tente man 3 qsort ou leia em http://linux.die.net/man/3/qsort
qsort
não precisa ser implementado usando Quicksort.
Embora não esteja exatamente na biblioteca padrão, https://github.com/swenson/sort tem apenas dois arquivos de cabeçalho que você pode incluir para obter acesso a uma ampla variedade de roteamentos de classificação incrivelmente rápidos, como:
#define SORT_NAME int64 #define SORT_TYPE int64_t #define SORT_CMP ( x , y ) (( x ) - ( y )) #include "sort.h" / * Agora você tem acesso a int64_quick_sort, int64_tim_sort, etc., por exemplo, * / int64_quick_sort ( arr , 128 ); / * Presume que você tenha algum int * arr ou int arr [128]; * /
Isso deve ser pelo menos duas vezes mais rápido que a biblioteca padrão qsort
, já que não usa ponteiros de função e tem muitas outras opções de algoritmo de classificação para escolher.
Está no C89, então deve funcionar basicamente em todos os compiladores C.
tente qsort
em stdlib.h.
Use qsort()
em <stdlib.h>
.
@paxdiablo A qsort()
função está de acordo com a ISO / IEC 9899: 1990 (`` ISO C90 '').
Existem várias funções de classificação C disponíveis em stdlib.h
. Você pode fazer man 3 qsort
em uma máquina Unix para obter uma lista deles, mas eles incluem: