Was ist der beste Weg, um den Median zu verfolgen?

8

Ich habe eine Frage gelesen und suche nach Informationen zur Lösung:

Zahlen werden zufällig generiert und in einem (expandierenden) Array gespeichert. Wie würden Sie den Median verfolgen?

Es gibt zwei Datenstrukturen, die das Problem lösen können. Einer ist der ausgeglichene Binärbaum, der andere sind zwei Haufen, die die größte Hälfte und die kleinste Hälfte der Elemente verfolgen. Ich denke, diese beiden Lösungen haben die gleiche Laufzeit wie O(n lg n), bin mir aber meines Urteils nicht sicher.

Was ist der beste Weg, um den Median zu verfolgen?

Mein Versuch:

In dieser Frage , Ich denke, ein Haufen ist der beste Weg, um den Median zu verfolgen. Es gibt zwei Haufen, den großen und den kleinen Haufen, die nicht sequentiell sein müssen. Zunächst berechnen wir den Mittelwert der Elemente im Array. Wenn das Element kleiner als der Mittelwert ist, setzen wir die Zahl auf den kleinen Haufen. Im Gegenteil, wir setzen die Nummer auf den großen Haufen. Wenn die Anzahl des großen Haufens gleich der Anzahl des kleinen Haufens ist, ist der größte im kleinen und der kleinste im großen Haufen der Median. Wenn die beiden Heaps unterschiedliche Größen haben, wird das Stammelement einfach aus dem Heap mit der größeren Größe entfernt und an die Wurzel des kleineren Heaps verschoben. Bei großen Heaps ist das Root-Element das kleinste und bei kleinen Heaps das Root-Element das größte. Auf diese Weise, wenn die beiden Haufen die gleiche Größe oder einen digitalen Unterschied haben,

Ich denke, diese Lösung hat die Laufzeit als O (m * n), m bedeutet die Zeiten, zu denen wir die Unwuchthaufen anpassen.

Ist dies der beste Weg, um den Median zu verfolgen?

Steven Mou
quelle
Wenn Sie nur den Median verfolgen müssen, haben die beiden im Wesentlichen die gleiche Komplexität, aber der Heap-basierte Ansatz benötigt weniger Speicher (seine Struktur ist implizit, anstatt Zeiger zu erfordern) und im Allgemeinen auch schneller (weil er normalerweise zusammenhängend gespeichert wird) verbessert normalerweise die Cache-Nutzung).
Jerry Coffin
2
stackoverflow.com/questions/2579912/… wäre eine lineare Lösung, wenn Sie eine wollten.
JB King
2
Hehe - std::nth_elementjemand?
Billy ONeal
5
Das klingt eigentlich eher nach einer Frage für SO als hier.
Mark B
Der Mittelwert kann so täuschen, dass er bedeutungslos ist. Wenn Sie sich nur vorstellen, haben Sie viele kleine Zahlen (z. B. 1..999) und 10 ^ 8. Der Mittelwert für diese 1000 Zahlen ist ~ 10 ^ 5, so dass Sie am Ende alles außer 10 ^ 8 in den kleinen Haufen legen. Daher weist der Algorithmus ein schlechtes Worst-Case-Verhalten auf.
user281377

Antworten:

1

Es gibt wahrscheinlich mehr als 2 Datenstrukturen, die dieses Problem lösen. Sehen Sie sich ungefähre Mediane und andere Quantile in einem Durchgang und mit begrenztem Speicher an

Sie benutzen keine zwei Haufen. Ich stelle mir vor, Sie könnten ihren Algorithmus ändern, um regelmäßig einen ungefähren Medianwert zu erhalten. Wie gut eine Annäherung sein würde, hängt natürlich von vielen Faktoren ab, nicht zuletzt davon, wie viele Daten den Algorithmus durchlaufen haben.

Bruce Ediger
quelle
0

Eine bessere Lösung ist die Verwendung einer Überspringliste. Da die Liste, in die Sie einfügen möchten, immer als sortierte Liste verwaltet wird (aufgrund der Art und Weise, wie Sie sie erstellen), ist die Komplexität des Einfügens O (log n). Sie werden die Tatsache ausnutzen, dass Sie beim ersten Einfügen den Median zu Nullkosten erhalten (das eingefügte Element ist der Median). Nach jeder weiteren Einfügung wird Ihre Liste weiterhin sortiert, und der Median selbst wird um einen einzelnen Index nach oben oder unten verschoben, und dieser Vergleich ist O (1).

Gesamtkomplexität = O (log n)

Michael Hays
quelle
Die Gesamtkomplexität für jedes Element ist O(log n)- das Einfügen von n Elementen hat eine Komplexität vonO(n log n)
Greg Jackson
1
Sicher, aber für einen "laufenden Median" könnte man argumentieren, dass Sie eine unbegrenzte Menge von Elementen einfügen, aber es macht wenig Sinn zu sagen, dass die Komplexität O ist (unendlich log n). ;-)
Michael Hays
Eh ... ok, meine Antwort ist vielleicht nicht besser als Haufen. Der Fibonacci-Haufen hat eine Insertion von O (1) und eine Deletion von O (lg n). Ich habe es einfach nie benutzt.
Michael Hays
0

Tatsächlich können Sie den Median in O (n) -Operationen nur finden, indem Sie die k - kleinste Zahl in einer Liste finden. Weitere Informationen finden Sie im Auswahlalgorithmus für den Median der Mediane .

Ruslan Kabalin
quelle
Sind Sie sicher, dass dies schrittweise verwendet werden kann ?
Joey Adams