Wenn Sie diese Algorithmen analysieren möchten, müssen Sie // Dostuff definieren, da dies das Ergebnis wirklich ändern kann. Nehmen wir an, Dostuff erfordert eine konstante Anzahl von O (1) Operationen.
Hier sind einige Beispiele mit dieser neuen Notation:
Für Ihr erstes Beispiel, das lineare Verfahren: Das ist richtig!
AUF):
for (int i = 0; i < myArray.length; i++) {
myArray[i] += 1;
}
Warum ist es linear (O (n))? Wenn wir dem Eingang (Array) zusätzliche Elemente hinzufügen, nimmt die Anzahl der Operationen proportional zur Anzahl der hinzugefügten Elemente zu.
Wenn also eine Operation erforderlich ist, um eine Ganzzahl irgendwo im Speicher zu erhöhen, können wir die Arbeit der Schleife mit f (x) = 5x = 5 zusätzlichen Operationen modellieren. Für 20 zusätzliche Elemente führen wir 20 zusätzliche Operationen durch. Ein einzelner Durchgang eines Arrays ist in der Regel linear. Dies gilt auch für Algorithmen wie Bucket Sort, die die Datenstruktur ausnutzen können, um eine Sortierung in einem einzigen Durchgang eines Arrays durchzuführen.
Ihr zweites Beispiel wäre ebenfalls korrekt und sieht folgendermaßen aus:
O (N ^ 2):
for (int i = 0; i < myArray.length; i++) {
for (int j = 0; j < myArray.length; j++) {
myArray[i][j] += 1;
}
}
In diesem Fall müssen wir für jedes zusätzliche Element im ersten Array i ALLES von j verarbeiten. Durch Hinzufügen von 1 zu i wird j tatsächlich hinzugefügt (Länge von j). Sie haben also Recht! Dieses Muster ist O (n ^ 2), oder in unserem Beispiel ist es tatsächlich O (i * j) (oder n ^ 2, wenn i == j, was häufig bei Matrixoperationen oder einer quadratischen Datenstruktur der Fall ist.
Ihr drittes Beispiel ist, wo sich die Dinge in Abhängigkeit von Dostuff ändern. Wenn der Code wie geschrieben ist und do stuff eine Konstante ist, ist es eigentlich nur O (n), weil wir 2 Durchgänge eines Arrays der Größe n haben und 2n auf n reduziert wird. Die Schleifen, die außerhalb voneinander liegen, sind nicht der Schlüsselfaktor, der 2 ^ n-Code erzeugen kann. Hier ist ein Beispiel für eine Funktion, die 2 ^ n ist:
var fibonacci = function (n) {
if (n == 1 || n == 2) {
return 1;
}
else {
return (fibonacci(n-2) + fibonacci(n-1));
}
}
Diese Funktion ist 2 ^ n, da jeder Aufruf der Funktion ZWEI zusätzliche Aufrufe der Funktion (Fibonacci) erzeugt. Mit jedem Aufruf der Funktion verdoppelt sich der Arbeitsaufwand! Das wächst super schnell, als würde man einer Hydra den Kopf abschneiden und jedes Mal zwei neue sprießen lassen!
Wenn Sie für Ihr letztes Beispiel eine nlgn-Sortierung wie "Merge-Sort" verwenden, haben Sie Recht, dass dieser Code O (nlgn) lautet. Sie können jedoch die Struktur der Daten ausnutzen, um in bestimmten Situationen schnellere Sortierungen zu entwickeln (z. B. über einen bekannten, begrenzten Wertebereich von 1 bis 100). Wenn also eine O (nlgn) -Sorte neben einer Operation steht, die weniger als O (nlgn) Zeit benötigt, ist die Gesamtzeitkomplexität O (nlgn).
In JavaScript (zumindest in Firefox) lautet die Standardsortierung in Array.prototype.sort () in der Tat MergeSort. Sie suchen also bei O (nlgn) nach Ihrem endgültigen Szenario.