Es ist nur eine leichte Änderungen an Ihrer comparizon Funktionsbibliothek qsort stabil zu machen. Siehe Link here
So etwas wie unten tun sollte den Trick (ungetestet, seien Sie vorsichtig):
int comp_on_price(const void *a, const void *b)
{
if ((*(B *)a).price < (*(B *)b).price)
return 1;
else if ((*(B *)a).price > (*(B *)b).price)
return -1;
else
// if zero order by addresses
return a-b;
}
Dies würde funktionieren, wenn Sie a und b in demselben Adressraum garantieren kann (zwei Zeiger im selben Array) und dass jeder Vergleich eine größere Gesamtordnung des Arrays ergibt, werden Adressen niedrigerer Strukturen dazu neigen, noch langsamer zu werden. Dies gilt für Blasensorten oder ähnliches. Das würde auch für eine triviale Implementierung von QucikSort funktionieren (was qsort nicht ist). Für andere Algorithmen oder jeden Algorithmus, der zusätzlichen Adressraum für temporäre Speicherung verwendet (möglicherweise für Optimierungszwecke), ist diese Eigenschaft nicht wahr.
Wenn das, was Sie sortieren, einen eindeutigen Bezeichner in verglichenen Elementen enthält (im aktuellen Beispiel wahrscheinlich für Feld-ID), wäre eine andere Methode, die Sortierung stabil zu machen, der Vergleich dieser Elemente. Sie könnten zu diesem Zweck auch einen solchen eindeutigen Schlüssel in einem neuen Feld hinzufügen, aber da er mehr Speicher verwendet, sollten Sie die dritte Option, die weiter unten beschrieben wird, beachten.
Meine bevorzugte Methode wäre immer noch eine dritte, sortiere nicht direkt ein Array von Strukturen, sondern sortiere ein Array von Zeigern auf tatsächliche Strukturelemente. Dies hat mehrere gute Eigenschaften. Zuerst können Sie Arrays der Struktur, auf die gezeigt wird, vergleichen, da sie sich nicht ändert und die Sortierung stabil macht.
Die Vergleichsfunktion wird sich so etwas wie:
int comp_on_price(const void *a, const void *b)
{
if ((*(B **)a)->price < (*(B **)b)->price)
return 1;
else if ((*(B **)a)->price > (*(B **)b)->price)
return -1;
else
// if zero, order by addresses
return *(B **)a-*(B **)b;
}
Andere gute Eigenschaften ist, dass es um Strukturen vermeiden bewegen, während das Sortieren, es müssen nur bewegende Zeiger, und das kann das spart Zeit sein. Sie können auch mehrere solcher Zeigerarrays behalten, die mehrere geordnete Zugriffe auf Array-Elemente gleichzeitig ermöglichen.
Nachteile sind, dass es etwas Speicher benötigt und dass der Zugriff auf Elemente etwas langsamer ist (eine Ebene der Indirektion mehr).
Sie können nicht wirklich _say_ was es ist O-ness ist, da es nicht verpflichtet ist, quicksort zu sein :-) – paxdiablo
ich glaube qsort ist nicht stabil ich mag falsch liegen? – learner123
Und Sie können es schneller (im Durchschnitt) –