C standart kitaplığında sıralama yapmak için herhangi bir kitaplık işlevi var mı?
C standart kitaplığında sıralama yapmak için herhangi bir kitaplık işlevi var mı?
Yanıtlar:
qsort()
aradığınız işlev. Onu veri dizinize, o dizideki elemanların sayısına, her bir elemanın boyutuna ve bir karşılaştırma fonksiyonuna bir işaretçi ile çağırırsınız.
Sihrini yapar ve diziniz yerinde sıralanır. Bir örnek aşağıdaki gibidir:
#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
" Nokta 4 "işlevi İki eleman eşit olarak karşılaştırılırsa, sonuçta ortaya çıkan sıralı dizideki sırası belirtilmez."
C / C ++ standart kitaplığı işlevi <stdlib.h>
içerir qsort
.
Bu dünyadaki en iyi hızlı sıralama uygulaması değil, ancak yeterince hızlı ve kullanımı ÇOK KOLAY ... qsort'un resmi sözdizimi:
qsort(<arrayname>,<size>,sizeof(<elementsize>),compare_function);
Gerçekleştirmeniz gereken tek şey, uygun veri yapısına dönüştürülebilen "const void" türünde iki bağımsız değişken alan ve ardından şu üç değerden birini döndüren karşılaştırma_işlevidir:
1. Tam sayılar listesinin karşılaştırılması :
sadece, eğer tam sayılara a ve b dökme x < y
, x-y
negatif olduğu x == y
, x-y = 0
, x > y
, x-y
pozitiftir
x-y
bu ters :) yapmak için bir kısayol yöntemdir *x - *y
için *y - *x
azalan sıralama için / geri sipariş
int compare_function(const void *a,const void *b) {
int *x = (int *) a;
int *y = (int *) b;
return *x - *y;
}
2. Bir dizi listesinin karşılaştırılması :
Dizgeyi karşılaştırmak için lib strcmp
içinde işleve ihtiyacınız var <string.h>
.
strcmp
varsayılan olarak -ve, 0, ve uygun bir şekilde dönecektir ... ters sırayla sıralamak için, strcmp tarafından döndürülen işareti ters çevirmek yeterlidir
#include <string.h>
int compare_function(const void *a,const void *b) {
return (strcmp((char *)a,(char *)b));
}
3. Kayan noktalı sayıların karşılaştırılması :
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. Kayıtları bir anahtara göre karşılaştırma :
Bazen kayıt gibi daha karmaşık şeyleri sıralamanız gerekir. qsort
Kitaplığı kullanarak yapmanın en basit yolu burada .
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
, karşılaştırıcıya iletilen değerlerin her ikisi de olarak int *
gizlenir void *
. Bu char *
nedenle, bir dizi sıralarken , karşılaştırıcıya iletilen değerlerin her ikisi de olarak char **
gizlenir void *
. Bu nedenle, doğru kod olması gerekiyor: 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;
veya basit bir ifade istiyorsanız, o zaman return (x > y) - (x < y);
. Bu her zaman C düzeyinde iki karşılaştırmayı değerlendirir, ancak optimize edici bundan kaçınabilir. Çıkarma, işaretsiz değerlerde çalışmaz. İlk sürüm, bir dizi karşılaştırma ile uğraşırken iyi çalışır - önce bir yapının 2 tam sayı üyesini ve eşitlerse, sonra iki çift, sonra iki dizgiyi karşılaştırır. Bunu yapmanın birden fazla yolu vardır, C ve Perl olarak.
Elbette: qsort()
bir tür uygulamasıdır (adından da anlaşılacağı gibi hızlı sıralama gerekmez).
Man 3 qsort'u deneyin veya http://linux.die.net/man/3/qsort adresinde okuyun
qsort
Quicksort kullanılarak uygulanması gerekmez.
Tam olarak standart kitaplıkta olmasa da, https://github.com/swenson/sort , çok çeşitli inanılmaz hızlı sıralama rotalarına erişmek için ekleyebileceğiniz yalnızca iki başlık dosyasına sahiptir, örneğin:
#define SORT_NAME int64 #define SORT_TYPE int64_t # tanımla SORT_CMP (x, y) ((x) - (y)) #include "sort.h" / * Artık int64_quick_sort, int64_tim_sort vb. Erişiminiz var, örneğin, * / int64_quick_sort (dizi, 128); / * Bazı int * arr veya int arr [128] 'a sahip olduğunuzu varsayar; * /
Bu, standart kitaplığın en az iki katı hızlı olmalıdır qsort
, çünkü işlev işaretçileri kullanmaz ve aralarından seçim yapabileceğiniz birçok başka sıralama algoritması seçeneği vardır.
C89'da, bu nedenle temelde her C derleyicisinde çalışmalıdır.
qsort
stdlib.h'de deneyin .
İçinde kullanılabilen birkaç C sıralama işlevi vardır stdlib.h
. man 3 qsort
Bunların bir listesini almak için bir unix makinesinde yapabilirsiniz , ancak şunları içerir: