Ich bin daran interessiert, ein Array positiver ganzzahliger Werte in linearer Zeit zu sortieren (im RAM-Modell mit einheitlichem Kostenmaß, dh ganze Zahlen können bis zu logarithmischer Größe haben, aber es wird angenommen, dass arithmetische Operationen auf sie angewendet werden Zeiteinheit). Natürlich ist dies mit vergleichsbasierten Sortieralgorithmen nicht möglich, daher bin ich daran interessiert, eine "ungefähre" Sortierung zu berechnen, dh eine Permutation von von , die in der Regel sortiert , sondern eine „gute Annäherung“ der sortierten Version nicht wirklich . Ich gehe davon aus, dass wir die ganzen Zahlen in absteigender Reihenfolge sortieren, da dies die Aussage der Fortsetzung ein wenig angenehmer macht, aber man könnte das Problem natürlich auch andersherum formulieren.
Ein mögliches Kriterium für eine ungefähre sortieren ist die folgende (*): lassen sein , für jeden , verlangen wir , dass (dh Die "quasi-sortierte" Liste wird von oben durch die abnehmende Funktion ) begrenzt. Es ist leicht zu erkennen, dass die tatsächliche Sortierung dies erfüllt: darf nicht größer als daher ist es höchstens ist und im Allgemeinen darf nicht größer sein als ist.
Zum Beispiel kann Anforderung (*) durch den folgenden Algorithmus erreicht werden (vorgeschlagen von @Louis). Meine Frage ist: Gibt es eine Arbeit zu dieser Aufgabe, ganze Zahlen in linearer Zeit "fast zu sortieren", indem eine Bedingung wie (*) auferlegt wird, die die reale Sortierung erfüllen würde? Hat der unten stehende Algorithmus oder eine Variante davon einen festgelegten Namen?
Bearbeiten: Der Algorithmus wurde korrigiert und es wurden weitere Erklärungen hinzugefügt
Algorithmus:
INPUT: V an array of size n containing positive integers
OUTPUT: T
N = Σ_{i<n} V[i]
Create n buckets indexed by 1..n
For i in 1..n
| Add V[i] into the bucket min(floor(N/V[i]),n)
+
For bucket 1 to bucket n
| For each element in the bucket
| | Append element to T
| +
+
Dieser Algorithmus funktioniert aus folgenden Gründen wie beabsichtigt:
- Befindet sich ein Element im Bucket dann ist .
wird in den Eimer gegeben , also
- Befindet sich ein Element im Bucket dann ist entweder oder .
j = min ( N / v , n ) , j = ⌊ N / v ⌋ j = n j = ⌊ N / v ⌋ j ≤ N / v < j + 1 N / ( j + 1 ) < v wird in den Eimer gestellt , also oder . Im ersten Fall ist was bedeutet, dass und somit .
Für gibt es höchstens Elemente in den Buckets von 1 bis .
Sei und sei die Gesamtzahl der Elemente in einem der Buckets 1..j. Mit 2. haben wir, dass jedes Element in einem Bucket (mit ) so ist, dass . Daher ist die Summe aller Elemente in den Buckets von bis größer als . Aber diese Summe ist auch weniger als so und somit , die uns gibt oder .V i i ≤ j N / ( j + 1 ) ≤ N / ( i + 1 ) < v K 1 j k × N / ( J + 1 ) K N k × N / ( j + 1 ) < K ≤ N k / ( j + 1 ) <
erfüllt (*), dh das te Element von ist so, dass
Nach 3. haben wir, dass , das te Element von , aus einem Bucket mit also .
Dieser Algorithmus benötigt eine lineare Zeit.
Die Berechnung von dauert linear. Buckets können mit einer verknüpften Liste implementiert werden, die -Einfügung und -Iteration aufweist. Die verschachtelte Schleife wird so oft ausgeführt, wie Elemente vorhanden sind (dh mal).