@Alexandru, der ganze Sinn der SO ist ein Ort für seine alle Programmierbezogene Frage, von jeder Spielstärke. Wo sollte Google die Nutzer Ihrer Meinung nach anleiten, wenn sie Ihre Abfrage verwenden? Die Mächte, die es wollen, kommen hierher - wenn SO der oberste Google-Link für diese Abfrage ist, ist unsere Arbeit erledigt.
Paxdiablo
1
Mein ursprünglicher Code war faul und wahrscheinlich ganz anders als bei einer Google-Suche. Nach all den Community-Eingaben haben Sie jedoch ein Beispiel für eine gute Implementierung der Verwendung von qsort.
Wiederholen Sie
@paxdiablo: Wenn dies der Fall ist, können sie genauso gut einfach die Standard-lib-Dokumentation hosten - ich bezweifle, dass diese Frage hier etwas über diese kanonische Referenz hinaus hinzufügen wird. Für einige komplexe Fälle vielleicht - aber nur um eine Grundfunktion zu finden?
Eamon Nerbonne
4
Selbst Fragen wie diese tragen zur vollständigen Vollständigkeit von SO als hilfreiche Datenbank für feststeckende Codierer bei.
Thomaspaulb
7
In vielen Fällen wissen die Leute auch nicht, wonach sie suchen sollen. Wenn Sie wissen, dass c eine Sortierfunktion namens qsort () hat, ist die Dokumentation leicht zugänglich. Wenn Sie jedoch nicht wissen, wonach Sie suchen sollen, welche Ressource Sie verwenden sollen.
Wiederholung
Antworten:
119
qsort()ist die Funktion, die Sie suchen. Sie rufen es mit einem Zeiger auf Ihr Datenarray, der Anzahl der Elemente in diesem Array, der Größe jedes Elements und einer Vergleichsfunktion auf.
Es macht seine Magie und Ihr Array ist an Ort und Stelle sortiert. Ein Beispiel folgt:
#include<stdio.h>#include<stdlib.h>int comp (constvoid* elem1,constvoid* elem2){int f =*((int*)elem1);int s =*((int*)elem2);if(f > s)return1;if(f < s)return-1;return0;}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]);return0;}
Sie sollten wirklich sizeof (* x) verwenden, falls Sie den Typ in Zukunft jemals ändern sollten, aber +1, um ein Beispiel bereitzustellen.
Paxdiablo
12
Im Allgemeinen führt ein Versuch, Ints durch Subtrahieren voneinander zu vergleichen, zu einem Überlauf. Es ist besser, sich von Anfang an von dieser schlechten Angewohnheit fernzuhalten. Verwenden Siereturn (f > s) - (f < s);
AnT
4
Okay, geändert gemäß den meisten Vorschlägen. Ich ziehe die Grenze, @ChrisL, wenn ich size_t benötige, da meine Arrays nie so groß werden :-) Und @AndreyT, obwohl dieser Hack klug ist, bevorzuge ich, dass mein Code lesbar ist :-)
paxdiablo
2
@paxdiablo: Dieser "Hack" ist eine etablierte Redewendung. Jeder Programmierer, der sein Salz wert ist, erkennt es sofort. Es hat keine negativen Auswirkungen auf die Lesbarkeit.
AnT
2
@JAamish ISO C99 Standard N1256, in "7.20.5.2 Die qsortFunktion" Punkt 4 "Wenn zwei Elemente als gleich verglichen werden, ist ihre Reihenfolge im resultierenden sortierten Array nicht angegeben."
12431234123412341234123
60
Die C / C ++ - Standardbibliothek <stdlib.h>enthält qsortFunktionen.
Dies ist nicht die beste schnelle Sortierimplementierung der Welt, aber sie ist schnell genug und SEHR EINFACH zu verwenden ... die formale Syntax von qsort lautet:
Das einzige, was Sie implementieren müssen, ist die compare_function, die zwei Argumente vom Typ "const void" akzeptiert, die in die entsprechende Datenstruktur umgewandelt werden können, und dann einen dieser drei Werte zurückgibt:
negativ, wenn a vor b sein sollte
0, wenn a gleich b ist
positiv, wenn a nach b sein sollte
1. Vergleichen einer Liste von ganzen Zahlen :
einfach gegossen , wenn a und b auf ganze Zahlen x < y, x-ynegativ ist , x == y, x-y = 0, x > y, x-ypositiv
ist x-yeine Abkürzung , wie es :) zu umkehren zu tun ist , *x - *yum *y - *xin abnehmenden / umgekehrte Reihenfolge zum Sortieren
int compare_function(constvoid*a,constvoid*b){int*x =(int*) a;int*y =(int*) b;return*x -*y;}
2. Vergleichen einer Liste von Zeichenfolgen :
Zum Vergleichen von Zeichenfolgen benötigen Sie strcmpFunktionen in <string.h>lib.
strcmpwird standardmäßig -ve, 0, ve entsprechend zurückgeben ... um in umgekehrter Reihenfolge zu sortieren, kehren Sie einfach das von strcmp zurückgegebene Vorzeichen um
Eine ziemlich gute Antwort, aber die Erklärung des Rückgabewerts der Vergleichsfunktion ist rückwärts. In einigen Beispielen führen Sie außerdem den xy-Trick aus, der zu fehlerhaften Ergebnissen führen kann (und weniger offensichtlich ist als ein einfacher Vergleich).
Adrian McCarthy
Nun, soweit es mich betrifft, funktioniert dies für jeden Wettbewerb;)
whacko__Cracko
5
Der xy-Trick funktioniert nicht, wenn der Unterschied zwischen x und y größer ist als der größte darstellbare int. Es ist also in Ordnung, wenn zwei positive Zahlen verglichen werden, aber der Vergleich, z. B. INT_MAX und -10, schlägt fehl. Upvoted, weil ich alle Beispiele für das Sortieren sehr unterschiedlicher Typen mag.
Douglas
2
Neben dem Überlaufproblem sowohl in der Ganzzahlkomparator- als auch in der Schlüsselkomparatorfunktion ist die Zeichenfolgenvergleichsfunktion falsch. Beim Sortieren eines Arrays von intwerden die an den Komparator übergebenen Werte beide int *als getarnt void *. Beim Sortieren eines Arrays von char *werden daher die an den Komparator übergebenen Werte beide char **als getarnt void *. Daher muss der richtige Code sein : int compare_function(const void *a,const void *b) { return (strcmp(*(char **)a, *(char **)b)); }.
Jonathan Leffler
1
Berücksichtigen if (x > y) return +1; else if (x < y) return -1; else return 0;Sie für überlaufsichere Ganzzahlvergleiche , oder wenn Sie einen einfachen Ausdruck wünschen, dann return (x > y) - (x < y);. Dies wertet immer zwei Vergleiche auf C-Ebene aus, aber der Optimierer kann dies möglicherweise vermeiden. Die Subtraktion funktioniert nicht bei vorzeichenlosen Werten. Die erste Version funktioniert gut, wenn Sie sich mit einer Reihe von Vergleichen befassen - indem Sie zuerst zwei ganzzahlige Elemente einer Struktur vergleichen und wenn sie gleich sind, dann zwei Doppelelemente, dann zwei Zeichenfolgen usw. Es gibt mehr als einen Weg, dies zu tun. in C sowie Perl.
Jonathan Leffler
9
Sicher: qsort()ist eine Implementierung einer Art (nicht unbedingt Quicksort, wie der Name vermuten lässt).
qsortmuss nicht mit Quicksort implementiert werden.
James McNellis
6
Https://github.com/swenson/sort ist zwar nicht genau in der Standardbibliothek enthalten, verfügt jedoch nur über zwei Header-Dateien, die Sie einschließen können, um Zugriff auf eine Vielzahl unglaublich schneller Sortierroutings zu erhalten, z.
#define SORT_NAME int64 #define SORT_TYPE int64_t #define SORT_CMP ( x , y ) (( x ) - ( y )) #include "sort.h" / * Sie haben jetzt Zugriff auf int64_quick_sort, int64_tim_sort usw., z. B. * /
int64_quick_sort ( arr , 128 ); / * Angenommen, Sie haben int * arr oder int arr [128]; * /
Dies sollte mindestens doppelt so schnell sein wie die Standardbibliothek qsort , da keine Funktionszeiger verwendet werden und viele andere Sortieralgorithmusoptionen zur Auswahl stehen.
Es ist in C89, sollte also in praktisch jedem C-Compiler funktionieren.
Es stehen mehrere C-Sortierfunktionen zur Verfügung stdlib.h. Sie können man 3 qsortauf einem Unix-Computer eine Liste erstellen, die jedoch Folgendes enthält:
Antworten:
qsort()
ist die Funktion, die Sie suchen. Sie rufen es mit einem Zeiger auf Ihr Datenarray, der Anzahl der Elemente in diesem Array, der Größe jedes Elements und einer Vergleichsfunktion auf.Es macht seine Magie und Ihr Array ist an Ort und Stelle sortiert. Ein Beispiel folgt:
quelle
return (f > s) - (f < s);
qsort
Funktion" Punkt 4 "Wenn zwei Elemente als gleich verglichen werden, ist ihre Reihenfolge im resultierenden sortierten Array nicht angegeben."Die C / C ++ - Standardbibliothek
<stdlib.h>
enthältqsort
Funktionen.Dies ist nicht die beste schnelle Sortierimplementierung der Welt, aber sie ist schnell genug und SEHR EINFACH zu verwenden ... die formale Syntax von qsort lautet:
Das einzige, was Sie implementieren müssen, ist die compare_function, die zwei Argumente vom Typ "const void" akzeptiert, die in die entsprechende Datenstruktur umgewandelt werden können, und dann einen dieser drei Werte zurückgibt:
1. Vergleichen einer Liste von ganzen Zahlen :
einfach gegossen , wenn a und b auf ganze Zahlen
x < y
,x-y
negativ ist ,x == y
,x-y = 0
,x > y
,x-y
positiv istx-y
eine Abkürzung , wie es :) zu umkehren zu tun ist ,*x - *y
um*y - *x
in abnehmenden / umgekehrte Reihenfolge zum Sortieren2. Vergleichen einer Liste von Zeichenfolgen :
Zum Vergleichen von Zeichenfolgen benötigen Sie
strcmp
Funktionen in<string.h>
lib.strcmp
wird standardmäßig -ve, 0, ve entsprechend zurückgeben ... um in umgekehrter Reihenfolge zu sortieren, kehren Sie einfach das von strcmp zurückgegebene Vorzeichen um3. Vergleichen von Gleitkommazahlen :
4. Vergleichen von Datensätzen anhand eines Schlüssels :
Manchmal müssen Sie komplexere Dinge sortieren, z. B. Aufzeichnungen. Hier ist der einfachste Weg, dies mit der
qsort
Bibliothek zu tun .quelle
int
werden die an den Komparator übergebenen Werte beideint *
als getarntvoid *
. Beim Sortieren eines Arrays vonchar *
werden daher die an den Komparator übergebenen Werte beidechar **
als getarntvoid *
. Daher muss der richtige Code sein :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;
Sie für überlaufsichere Ganzzahlvergleiche , oder wenn Sie einen einfachen Ausdruck wünschen, dannreturn (x > y) - (x < y);
. Dies wertet immer zwei Vergleiche auf C-Ebene aus, aber der Optimierer kann dies möglicherweise vermeiden. Die Subtraktion funktioniert nicht bei vorzeichenlosen Werten. Die erste Version funktioniert gut, wenn Sie sich mit einer Reihe von Vergleichen befassen - indem Sie zuerst zwei ganzzahlige Elemente einer Struktur vergleichen und wenn sie gleich sind, dann zwei Doppelelemente, dann zwei Zeichenfolgen usw. Es gibt mehr als einen Weg, dies zu tun. in C sowie Perl.Sicher:
qsort()
ist eine Implementierung einer Art (nicht unbedingt Quicksort, wie der Name vermuten lässt).Probieren Sie man 3 qsort aus oder lesen Sie es unter http://linux.die.net/man/3/qsort
quelle
qsort
muss nicht mit Quicksort implementiert werden.Https://github.com/swenson/sort ist zwar nicht genau in der Standardbibliothek enthalten, verfügt jedoch nur über zwei Header-Dateien, die Sie einschließen können, um Zugriff auf eine Vielzahl unglaublich schneller Sortierroutings zu erhalten, z.
Dies sollte mindestens doppelt so schnell sein wie die Standardbibliothek
qsort
, da keine Funktionszeiger verwendet werden und viele andere Sortieralgorithmusoptionen zur Auswahl stehen.Es ist in C89, sollte also in praktisch jedem C-Compiler funktionieren.
quelle
versuchen Sie es
qsort
in stdlib.h.quelle
Verwenden Sie
qsort()
in<stdlib.h>
.@paxdiablo Die
qsort()
Funktion entspricht ISO / IEC 9899: 1990 ("ISO C90").quelle
Es stehen mehrere C-Sortierfunktionen zur Verfügung
stdlib.h
. Sie könnenman 3 qsort
auf einem Unix-Computer eine Liste erstellen, die jedoch Folgendes enthält:quelle