2010-12-29 12 views
1

Live-Code: http://jsfiddle.net/fCUZC/Kann mir jemand sagen, warum dieser JavaScript-Code kein Array anordnet?

//INPUT ARRAY: 
var input = [28,32,21,11,8,2,14,32,64]; 
//VARIABLE DECLARATION. a = highest number so far, b = position of that number 
entireLoop: 
for (var i = 1; i<=input.length; i++) 
{ 
    if(input[i] > input[i-1]) 
    { 
     for(var o = i; o>=0; o--) 
     { 
      if(input[i-1] > input[o]) 
      { 
       input.splice(i,0,input[o]); 
       input.splice((o+1),1); 
       continue entireLoop; 
      } 
      else if(input[o] > input[0]) 
      { 
       input.splice(0,0,input[o]); 
       input.splice((o+1),1); 
       continue entireLoop; 
      } 

     } 
    } 
} 
document.write(input); 

Ich versuche, das Array vom größten zum kleinsten zu bestellen, aber es gibt ein 32 irgendwo stecken. Ich weiß, dass es die Sortiermethode gibt, aber ich bin ein Neuling und möchte das selbst ausprobieren.

+1

Welchen Sortieralgorithmus halten Sie für dies? Scheint wie ein generelles Problem mit dem Design Ihres Algorithmus. – Simon

+2

Ist dieser Algorithmus Ihre Erfindung oder eine Implementierung? Es scheint ziemlich hungrig ... –

+0

Noch schlimmer ist, dass Zahlen doppelt sind und andere fehlen (doppelte 2 und fehlende 14) ... weit schlimmer als eine falsche 32 am Ende;) –

Antwort

5

** bearbeiten ** Schauen Sie sich zuerst die native .sort() Methode des Arrays an. Es lässt das ursprüngliche Array intakt und akzeptiert eine Vergleichsfunktion. Letzteres macht .sort() ziemlich mächtig.

var input = [28,32,21,11,8,2,14,32,64]; 

var low2high = function (a , b) { 
    return a > b; 
}; 

var high2low = function (a , b) { 
    return a < b; 
}; 

var resultHigh2low = input.sort(high2low); // [ 64,32,32,28,21,14,11,8,2 ]; 
var resultLow2high = input.sort(low2high); // [ 2,8,11,14,21,28,32,32,64 ]; 

Also, wenn wir BubbleSort (Link zur Verfügung gestellt von TJ Crowder, siehe OP Kommentare) verwenden möchten wir folgendes schreiben:

// javascript bubbleSort implementation 
var bubbleSort = function (list , comparison) { 
    var swapped; 
    var i; 
    var val; 

    list = [].concat(list); // do not destroy original 
    comparison = (typeof comparison == "function") ? comparison : function(a,b){return a > b;} 

    do { 
     i = list.length; 
     while (--i) { 
      if (i && comparison(list[ i ] , comparison[ i-1])) { 
       val = list[ i ]; 
       list[ i ] = list[ i - 1 ]; 
       list[ i - 1] = val; 
       swapped = true; 
      } 
     } 
    } while (swapped); 
    return list; 
} 

// using comparison functions from previous example. 
var resultHigh2low = bubbleSort(input , high2low); // [ 64,32,32,28,21,14,11,8,2 ]; 
var resultLow2high = bubbleSort(input , low2high); // [ 2,8,11,14,21,28,32,32,64 ]; 

Ermöglicht durch sie Schritt für Schritt gehen:

var bubbleSort = function (list , comparison) { 
    ..code.. 
} 

Unsere Funktion akzeptiert 2 Parameter, zuerst das Array und 2nd eine optionale Vergleichsfunktion.

var swapped; 
var i = list.length; 
var val; 

Wir speichern die Länge der Liste unter variablen i und erklären 2 leere Variablen (swapped und val) wir später verwenden werden.

list = [].concat(list); // do not destroy original 

Wir klonen die Liste mit [].concat(array) und überschreiben die lokale list Variable das Original intakt bleibt.

comparison = (typeof comparison == "function") ? comparison : function(a,b){return a > b;} 

Wir testen die typeof das comparison Argument, wenn es ein function ist wir, dass man verwenden, sonst fallen wir auf unsere eigenen comparison Funktion zurück. Unsere Fallback-Vergleichsfunktion gibt true zurück, wenn a größer als b ist.

do { 
    ..code.. 
} while (swapped); 

A do/while-Schleife mindestens einmal ausgeführt wird, unsere swapped Variable ist derzeit undefined so wird es als falsy interpretiert werden. Wenn unsere comparison-Funktion den Wert "true" zurückgibt, tritt ein Austausch auf und die Variable "" wird auf "true" gesetzt, sodass sie erneut durchlaufen wird.

while (--i) { 
    ..code.. 
} 

Here I Schleife von der Länge der Liste nach unten, der -- Operator wird vor den i Variable setzen, um sicherzustellen, wird behandelt, bevor irgendetwas würde i-- gehen nach while Auswertung falsch empfangenen Ergebnisse, da list[ list.length ] verursacht nicht existiert. Ich tue es immer so (schlimmes Habit vielleicht), aber wenn es dich verwirrt, gehe auf absolute Transparenz.

if (i && comparison(list[ i ] , comparison[ i-1])) { 
    ..code.. 
} 

Zuerst überprüfen wir, ob eine i truthy Wert (0 ausgewertet falsy) und führen wir die Funktion comparisonlist[ i ] und list[ i - 1 ] als a und b Parameter. Wenn die Funktion comparisontrue zurückgibt, führen wir einen Austausch durch.

val = list[ i ]; 
list[ i ] = list[ i - 1 ]; 
list[ i - 1] = val; 
swapped = true; 

Hier habe ich den Swap ohne Verwendung der .splice() Methode durchführen, es ist nur eine Vermutung atm., Aber ich glaube direkte Zuweisungen sind schneller als Funktionsaufrufe. Ich verwende die Variable val als Platzhalter. Nachdem der Austausch abgeschlossen ist, setze ich swapped auf True, damit unsere Do/While-Schleife fortgesetzt wird.

return list; 

Nun ... das Ergebnis zurückgeben.

Ich habe einige Überprüfungen ausgeschlossen, wie was tun wir, wenn die Länge der Liste 0 ist und was nicht. Grundsätzlich müssen wir beim Schreiben von Hilfsfunktionen auch mit der Fehlerbehandlung umgehen. Wenn Sie beispielsweise einen TypeError auslösen, wenn das übergebene Vergleichsargument keine Funktion ist, wird durch die Überprüfung der Vergleichsmethode ein boolescher Wert usw. zurückgegeben.

+0

Schöne Antwort. Müssen Sie nicht jede Schleife zurücksetzen? Sie sind von i = Listenlänge runter auf 0 gegangen, aber dann scheinen Sie nicht um es für die nächste Schleife zurückzusetzen. Ist das eine verpasste Linie von dir oder fehlt mir etwas? Auch ich mag "truthy" und "falsy". :) – Chris

+0

yeh, oopsy, good catch;) – BGerrissen

2
//INPUT ARRAY: 
var input = [28,32,21,11,8,2,14,32,64]; 
//VARIABLE DECLARATION. a = highest number so far, b = position of that number 
for (var i = 1; i<input.length; i++) 
{ 
    if(input[i] > input[i-1]) 
    { 
     for(var o = i-1; o>=0; o--) 
     { 
      if(input[i] > input[o]) 
      { 
       input.splice(i+1,0,input[o]); 
       input.splice((o),1); 
       i--; 
      }  
     } 
    } 
} 
document.write(input); 

Während es immer noch nicht gut ist, sollte es funktionieren. Denken Sie daran, ich habe dies kaum getestet und ich bin ziemlich unerfahren mit Javascript. Deine Absichten waren nicht schlecht und jeder muss irgendwo anfangen.

Das größte Problem war einfach die innere Bedingung. Ich kann Ihre Logik sehen, wie Sie rückwärts von dem großen Wert, den Sie gefunden haben, rückwärts blättern und alle kleineren Werte nach rechts schieben. Leider sind deine Indizes ein wenig aus. Sie müssen diese Schleife auch so lange ausführen, bis sie normal beendet wird, anstatt fortfahren zu müssen. Andernfalls wechseln Sie nur einen Wert. Wenn diese Bedingung behoben ist, wird die zweite nicht mehr benötigt.

Die alternative Form wäre, vom niedrigsten Index aus zu beginnen und den ersten Wert zu finden, der kleiner als Eingabe [i] ist, und ihn dort zu platzieren. Dies ist möglicherweise klarer.

Ich denke, das war ein ziemlich guter erster Schuss und war nicht so schwer zu arbeiten. Viel Glück!

+0

Scheint zu arbeiten a Charme für die Test-Eingänge, die ich versuchte. Gut gemacht. :) – Chris

Verwandte Themen