Das Finden der n kleinsten Elemente in einem list<float>
kann durch Sortieren der Liste und Auswählen der n kleinsten Elemente erfolgen. Aber es kann auch effizienter mit Haufen getan werden. Ich habe mehrere Implementierungen von Heaps für F # gefunden, aber keine Beispiele, wie sie für diesen Zweck verwendet werden können. Meine zwei Stolpersteine waren:Wie finde ich effizient die n kleinsten Elemente in einer Liste?
1) Ich konnte keinen Weg finden, einen Haufen von einer Liste zu schaffen. Alle Implementierungen, die ich gesehen habe, bieten eine Möglichkeit, einen leeren Heap zu erstellen und haben eine insert
Methode. Soll ich einen leeren Heap erstellen und Elemente einzeln einfügen? Das sieht langsam aus, was den Zweck zunichte machen würde.
2) Keine Umsetzung ein nLargest oder nSmallest Verfahren wie zum Beispiel des Python-Code:
from heapq import nlargest
lst = [9,1,6,4,2,8,3,7,5]
nlargest(3, lst) # Gives [9,8,7]
Gibt es eine einfache Möglichkeit, dieses Problem zu lösen?
Wenn Sie ein Array haben, können Sie ein Array in O (N) Zeit zu häufen , aber der Typ F # 'list' ist eine Datenstruktur mit verknüpften Listen, für die der Heap-Algorithmus O (N^2) Zeit wäre, da das Heap-Verfahren auf O (1) wahlfreiem Zugriff durch den Index zu seinem Array beruht. Ihre zwei Optionen sind also: 1) wandeln Sie Ihre Liste in ein Array (eine O (N) -Operation) um und haufen Sie sie (eine zweite O (N) -Operation), dann erhalten Sie die 3 kleinsten Elemente (3 O (log N) -Operationen) . Oder 2) sortiere einfach die Liste (O (N log N)) und nimm dann die 3 ersten Elemente daraus (3 O (1) -Operationen). Wenn Sie nicht erwarten, dass Ihre Liste riesig ist, würde ich sagen, machen Sie sich keine Sorgen: einfach sortieren. – rmunn
@rmunn Danke. Aber nur für den Fall, wie würde ich das Array häufen und die kleinsten Elemente bekommen? – Soldalma
Siehe https://www.cs.princeton.edu/~wayne/kleinberg-tardos/pdf/DemoHeapify.pdf für eine visuelle Demo und http://www.cs.toronto.edu/~krueger/cscB63h/w07/ Vorträge/Tut02.txt für einige Pseudocode. Kurz gesagt, fangen Sie mit dem Array an, und stellen Sie vom letzten Element bis zum ersten sicher, dass es kleiner ist als seine beiden Heap-Child-Elemente. Wenn nicht, vertauschen Sie es mit dem kleineren Kind und wiederholen Sie diesen Vorgang beim kleineren Kind. Und da die rechte Hälfte des Arrays keine Heap-Kinder hat, können Sie tatsächlich bei 'array.Length/2' beginnen und zu Index 0 gehen.Die Analyse des Algorithmus hat gezeigt, dass dies eine O (N) -Zeit benötigt. – rmunn