Sortieren nach QuickSort. Merge Sortieren ist ein Divide - und Conquer-Algorithmus. Es teilt Eingangs-Array in zwei Hälften, ruft sich für die beiden Hälften und vereinigt dann die beiden sortierten Hälften. Die merge () - Funktion wird verwendet, um zwei Hälften zusammenzuführen. Der Merge (arr, l, m, r) ist ein Schlüsselprozess, der annimmt, dass arrl..m und arrm1..r sortiert werden und die zwei sortierten Sub-Arrays zu einem zusammenführen. Siehe C-Implementierung für Details. Das folgende Diagramm aus wikipedia zeigt den kompletten Merge-Sortierprozess für ein Beispiel-Array. Wenn wir uns das Diagramm genauer ansehen, können wir sehen, dass das Array rekursiv in zwei Hälften geteilt wird, bis die Größe 1 ist. Sobald die Größe 1 ist, kommen die Merge-Prozesse in Aktion und beginnen, Arrays zurück zu verschmelzen, bis das gesamte Array vorliegt Zusammengeführt. Zeitkomplexität: Sortierfelder auf verschiedenen Maschinen. Merge Sort ist ein rekursiver Algorithmus, und die Zeitkomplexität kann als folgende Rekursionsrelation ausgedrückt werden. T (n) 2T (n 2) Das obige Rezidiv kann entweder mit dem Recurrence-Tree-Verfahren oder dem Master-Verfahren gelöst werden. Es fällt in Fall II der Master-Methode und Lösung des Rezidivs ist. Die Zeitkomplexität von Merge Sort ist in allen 3 Fällen (schlechteste, durchschnittliche und beste), da merge sort immer das Array in zwei Hälften teilt und lineare Zeit nimmt, um zwei Hälften zusammenzuführen. Algorithmisches Paradigma: Teilung und Eroberung Sortierung an Ort und Stelle: Nein in einer typischen Implementierung Anwendungen von Merge Sortieren Merge Sortieren ist für die Sortierung von verknüpften Listen in O (nLogn) Zeit nützlich. Bei verketteten Listen ist der Fall vor allem aufgrund der unterschiedlichen Speicherzuweisung unterschiedlich Von Arrays und verknüpften Listen. Im Gegensatz zu Arrays können verknüpfte Listenknoten nicht im Speicher benachbart sein. Im Gegensatz zum Array können wir in der verketteten Liste Objekte in der Mitte in O (1) Extraraum und O (1) Zeit einfügen. Daher kann der Merge-Vorgang der Merge-Sortierung ohne zusätzlichen Platz für verknüpfte Listen implementiert werden. In Arrays können wir wahlfreien Zugriff machen, da Elemente im Speicher kontinuierlich sind. Nehmen wir an, wir haben ein ganzzahliges (4-Byte) Array A und lassen uns die Adresse von A0 x dann auf Ai zugreifen, wir können direkt auf den Speicher (x i4) zugreifen. Im Gegensatz zu Arrays, können wir nicht tun, random access in verketteten Liste. Schnelles Sortieren erfordert eine Menge dieser Art von Zugriff. In verketteter Liste auf ith Index zugreifen, müssen wir jeden Knoten vom Kopf zum ithten Knoten reisen, da wir keinen durchgängigen Speicherblock haben. Daher erhöht sich der Overhead für schnelle Sortierung. Merge-Sortierung greift auf Daten nacheinander zu und die Notwendigkeit eines zufälligen Zugriffs ist gering. Inversion Count Problem, das in der externen SortierungTabelle 1: Maximale aller Schiebefenster mit Größe 3 in einem Array verwendet wird. Ein Paar Klammern zeigt ein Schiebefenster an. Analyse: Es ist nicht schwer, eine Lösung mit Brute Force zu erhalten: Scannen Sie die Nummern in jedem Schiebefenster, um seinen maximalen Wert zu erhalten. Die Gesamtzeitkomplexität ist O (nk), wenn die Länge des Arrays n ist und die Größe der Schiebefenster k ist. Die NSL-Lösung ist nicht die beste Lösung. Lassen Sie uns bessere Lösungen erforschen. Lösung 1: Maximalwert in einer Warteschlange Ein Fenster kann als Warteschlange betrachtet werden. Wenn es gleitet, wird eine Zahl in seinen Rücken gedrückt, und seine Frontseite heraus geklopft. Daher ist das Problem gelöst, wenn wir den maximalen Wert einer Warteschlange erhalten können. Es gibt keine einfachen Ansätze, um den maximalen Wert einer Warteschlange zu erhalten. Allerdings gibt es Lösungen, um den maximalen Wert eines Stacks zu erhalten, der ähnlich der im Blog 8220Stack mit der Funktion min () 8221 eingeführten Lösung ist. Zusätzlich kann eine Queue auch mit zwei Stacks implementiert werden (Details werden in einem anderen Blog besprochen) 8220Queue implementiert mit zwei Stacks 8221). Wenn ein neuer Typ von Warteschlange mit zwei Stapeln implementiert wird, in denen eine Funktion max () definiert ist, um den Maximalwert zu erhalten, ist der Maximalwert in einer Warteschlange die grßere Anzahl der beiden Maximalzahlen in zwei Stapeln. Diese Lösung ist praktikabel. Allerdings haben wir möglicherweise nicht genug Zeit, um alle Code zu schreiben, um unsere eigenen Warteschlange und Stapel-Datenstrukturen bei Interviews zu implementieren. Lassen Sie uns weiterhin eine präzisere Lösung erforschen. Lösung 2: Speichern des Maximalwertes in die Vorderseite einer Warteschlange Statt alle Zahlen innerhalb eines Schiebefensters in eine Warteschlange zu schieben, versuchen wir, die Kandidaten maximal in eine Warteschlange zu schieben. Lassen Sie uns das Array als Beispiel nehmen, um die Lösung Schritt für Schritt zu analysieren. Die erste Zahl im Array ist 2, wir schieben es in eine Warteschlange. Die zweite Zahl ist 3, die größer als die vorhergehende Zahl 2 ist. Die Zahl 2 sollte weggepoppt werden, weil sie kleiner als 3 ist und es keine Chance hat, der maximale Wert zu sein. Es gibt nur eine Zahl in der Warteschlange links, wenn wir Pop 2 auf der Rückseite und drücken Sie 3 auf der Rückseite. Die Operationen sind ähnlich, wenn wir die nächste Zahl 4 drücken. Es gibt nur eine Zahl 4 übrig in der Warteschlange. Nun hat das Schiebefenster bereits drei Elemente, wir können den maximalen Wert an der Vorderseite der Warteschlange erhalten. Wir fahren fort, die vierte Zahl zu drücken. Es wird an der Rückseite der Warteschlange gedrückt, weil es kleiner als die vorherige Nummer 4 ist und es möglicherweise eine maximale Anzahl in der Zukunft sein wird, wenn die vorherigen Zahlen abgestoßen werden. Es gibt zwei Zahlen, 4 und 2, in der Warteschlange, und 4 ist das Maximum. Die nächste zu schiebende Zahl ist 6. Da sie größer als die vorhandenen Nummern 4 und 2 ist, können diese beiden Nummern abgehackt werden, da sie keine Chance haben, das Maximum zu sein. Jetzt gibt es nur eine Zahl in der Warteschlange, die 6 ist, nachdem die aktuelle Nummer gedrückt wird. Selbstverständlich ist das Maximum 6. Die nächste Zahl ist 2, die in die Rückseite der Warteschlange gedrückt wird, weil sie kleiner als die vorhergehende Zahl 6 ist. Es gibt zwei Zahlen in der Warteschlange, 6 und 2 und die Zahl 6 an Die Vorderseite der Warteschlange ist der Maximalwert. Es ist Zeit, die Zahl 5 zu drücken. Weil sie größer als die Zahl 2 an der Rückseite der Warteschlange ist, wird 2 ausgeschaltet und dann wird 5 gedrückt. Es gibt zwei Zahlen in der Warteschlange, 6 und 5, und die Zahl 6 an der Vorderseite der Warteschlange ist der Maximalwert. Nun lassen Sie uns die letzte Nummer 1 drücken. Es kann in die Warteschlange geschoben werden. Es ist erkennbar, dass die Zahl an der Vorderseite den Rahmen des aktuellen Schiebefensters übersteigt, und es sollte abgestoßen werden. Wie wissen wir, ob die Nummer an der Vorderseite der Warteschlange ist aus Schiebefenster Statt der Speicherung von Zahlen in der Warteschlange direkt, können wir Indizes statt. Wenn der Abstand zwischen dem Index an der Vorderseite der Warteschlange und dem Index der aktuellen Anzahl, die gedrückt werden soll, größer oder gleich der Fenstergröße ist, ist die Zahl, die dem Index an der Schriftart der Warteschlange entspricht, außerhalb des gleitenden Fensters. Der oben beschriebene Analyseprozess ist in Tabelle 2 zusammengefasst. Tabelle 2: Der Prozess, um die maximale Anzahl aller Schiebefenster mit Fenstergröße 3 im Array zu erhalten. In der Spalte 8220Indices in queue8221 ist die Zahl innerhalb eines Paares von Klammern die Zahl, die durch die Zahl vor ihr im Array indexiert wird. Wir können eine Lösung auf der Grundlage der obigen Analyse implementieren. Einige Beispielcode in C ist unten gezeigt, die die Art deque von STL verwendet. Vectorlt int gt maxInWindows (const vectorlt int gtamp Zahlen, int windowSize) vectorlt int gt maxInSlidingWindows if (numbers. size () gt windowSize ampamp windowSize gt 1) Die Lösung 2 verfolgt tatsächlich alle möglichen Maxima im Schiebefenster. Wenn also das Fenster verschoben wird, muss es entscheiden, ob die erste Nummer in der Warteschlange gelöscht wird und dann die neue Nummer in die Warteschlange gestellt und die neue Nummer mit der zweitletzten Nummer in dieser Warteschlange verglichen wird, wenn die zweitletzte Zahl Kleiner ist als diese Zahl zu löschen und dann mit der dritten neuesten Zahl zu vergleichen. Also im schlimmsten Fall, ich denke, es ist O (nk) Zeit Komplexität. Das ist ziemlich schlecht.
No comments:
Post a Comment