Schnelle Sortieralgorithmen für Arrays mit meist duplizierten Elementen?

8

Was sind effiziente Möglichkeiten, um Arrays zu sortieren, die meist nur einen kleinen Satz duplizierter Elemente enthalten? Das ist eine Liste wie:

{10, 10, 55, 10, 999, 8851243, 10, 55, 55, 55, 10, 999, 8851243, 10}

Unter der Annahme, dass die Reihenfolge der equal -Elemente keine Rolle spielt, was sind gute Worst-Case- / Durchschnitts-Algorithmen?

    
donnyton 18.11.2011, 05:21
quelle

5 Antworten

14

In der Praxis können Sie zuerst einmal durch das Array iterieren und eine Hash-Tabelle verwenden, die die Anzahl der Vorkommen der einzelnen Elemente zählt (dies ist O (n), wobei n = Größe der Liste). Dann nimm alle eindeutigen Elemente und sortiere sie (das ist O (k log k) mit k = Anzahl der eindeutigen Elemente), und dehne dann dieses zurück zu einer Liste von n Elementen in O (n) Schritten und erhole die Zählungen von Hash-tabelle. Wenn k & lt; & lt; n Sie sparen Zeit.

    
Antti Huima 18.11.2011, 06:06
quelle
2

Nicht der beste Algorithmus, aber einfach:
Du kannst alles in einen Trie setzen und die Blätter als Zähler haben. Das sollte O (n * m) annehmen, wobei n die Anzahl der Elemente und m die Größe des größten Elements ist (typischerweise wäre das eine Konstante, aber nicht notwendigerweise). Dann vorbestellen Sie die Krawatte und geben counter Elemente des aktuellen Schlüssels aus, wenn Sie ein Blatt treffen. Das sollte nur O (n + p) nehmen, wobei p die Größe des Trie ist, was im Vergleich zu n winzig sein sollte.

    
harold 18.11.2011 11:02
quelle
2

Ich würde Counting sort mit einer Mapping-Funktion versuchen. Ie. Sie werden nicht das Array der Frequenzen verwenden, dessen Größe dem Bereich der Elemente entspricht, stattdessen würden Sie über das Array iterieren, verschiedene Elemente aufschreiben und sie in einer Mapping-Funktion für das Array von Frequenzen verwenden.

Auf diese Weise hat der Algorithmus nur eine zusätzliche Iteration und eine Mapping-Funktion, die in einer konstanten Zeit funktionieren sollte (unter Verwendung einer King of Hash-Tabelle). Die Komplexität dieses Ansatzes wäre O(n) , was optimal sein sollte.

    
malejpavouk 18.11.2011 17:54
quelle
1

Implementierung in C ++ basierend auf Algo wie von @Antti Huima vorgeschlagen

  • Zählen Sie die Häufigkeiten und speichern Sie sie in der Hashtabelle.
  • Elemente in Hashtabellen sortieren.
  • überschreibt Input-Array mit sortierten Elementen in Abhängigkeit von den Frequenzen.

    %Vor%
blueskin 08.08.2016 20:26
quelle
0

IMO Pidgeonhole-Sortierung ist ein gutes Beispiel für solche Daten.

Ich werde ein wenig klarstellen: Wenn Sie wissen, dass die Menge der einzigartigen Elemente im Array vernünftig ist und Sie wissen, dass es viele Duplikate gibt, würde ich mir vorstellen, sowas wie das Zählen von Sortierung zu implementieren, aber die Liste der "Buckets" dynamisch zu machen . Nach dem ersten Durchlauf werden Sie die Duplikate los, sortieren Sie dann das Array ohne Duplikate mit einem guten Sortieralgorithmus und stellen Sie das sortierte Array wieder her, ähnlich wie das Zählen von Sort.

    
Alex Nikolaenkov 18.11.2011 05:29
quelle