Sie können einfach die Anzahl der Inversionen in der Liste zählen.
Inversion
Eine Inversion in einer Folge von Elementen des Typs T
ist ein Paar von Folgeelementen, die gemäß einer bestimmten Reihenfolge <
auf der Menge von T
's in der falschen Reihenfolge erscheinen .
Aus Wikipedia :
Formell sei A(1), A(2), ..., A(n)
eine Folge von n
Zahlen.
Wenn i < j
und A(i) > A(j)
, dann heißt das Paar (i,j)
eine Inversion von A
.
Die Inversionsnummer einer Sequenz ist ein gängiges Maß für ihre Sortierung.
Formal wird die Inversionszahl als die Anzahl der Inversionen definiert, d. H.
Betrachten Sie die Beispielsequenz, um diese Definitionen klarer zu machen 9, 5, 7, 6
. Diese Sequenz hat die Inversionen (0,1), (0,2), (0,3), (2,3)
und die Inversionsnummer 4
.
Wenn Sie einen Wert zwischen 0
und möchten 1
, können Sie die Inversionszahl durch dividieren N choose 2
.
Um tatsächlich einen Algorithmus zum Berechnen dieser Punktzahl für die Sortierung einer Liste zu erstellen, haben Sie zwei Ansätze:
Ansatz 1 (deterministisch)
Ändern Sie Ihren bevorzugten Sortieralgorithmus, um zu verfolgen, wie viele Inversionen während der Ausführung korrigiert werden. Obwohl dies nicht trivial ist und je nach ausgewähltem Sortieralgorithmus unterschiedliche Implementierungen aufweist, erhalten Sie einen Algorithmus, der (in Bezug auf die Komplexität) nicht teurer ist als der Sortieralgorithmus, mit dem Sie begonnen haben.
Wenn Sie diesen Weg einschlagen, beachten Sie, dass es nicht so einfach ist, "Swaps" zu zählen. Mergesort ist beispielsweise der schlimmste Fall O(N log N)
. Wenn es jedoch in einer Liste ausgeführt wird, die in absteigender Reihenfolge sortiert ist, werden alle N choose 2
Inversionen korrigiert . Das sind O(N^2)
Inversionen, die im O(N log N)
Betrieb korrigiert wurden. Daher müssen einige Operationen zwangsläufig mehr als eine Inversion gleichzeitig korrigieren. Sie müssen mit Ihrer Implementierung vorsichtig sein. Hinweis: Sie können dies mit O(N log N)
Komplexität tun , es ist nur schwierig.
Verwandte: Berechnung der Anzahl der "Inversionen" in einer Permutation
Ansatz 2 (stochastisch)
- Zufällige Stichprobenpaare
(i,j)
, wobeii != j
- Bestimmen Sie für jedes Paar, ob
list[min(i,j)] < list[max(i,j)]
(0 oder 1)
- Berechnen Sie den Durchschnitt dieser Vergleiche und normalisieren Sie dann um
N choose 2
Ich persönlich würde mich für den stochastischen Ansatz entscheiden, es sei denn, Sie haben ein Erfordernis der Genauigkeit - schon allein deshalb, weil es so einfach zu implementieren ist.
Wenn Sie wirklich einen Wert ( z'
) zwischen -1
(sortiert absteigend) bis 1
(sortiert aufsteigend) möchten , können Sie den Bereich über ( z
), der zwischen 0
(sortiert aufsteigend) und 1
(sortiert absteigend) liegt, mit dieser Formel einfach diesem Bereich zuordnen ::
z' = -2 * z + 1