Verkettete Listen mit Sortierfunktion

 

Quellcode (JS)

/* ****************************************************************************************** *
 * Das Script kann frei verwendet werden, dieser Kommentar sowie die Nennung des Nicks
 * und der URL müssen jedoch erhalten bleiben.
 *
 *                                                           (c) Quaese (www.quaese.de), 2009
 * ****************************************************************************************** */
$(function() {
  $("#sortable1, #sortable2").sortable({
    connectWith: '.connectedSortable',
    revert: true,
    update: function(evt, ui){
      // Array aller LI-Elemente erstellen
      arrLI = new Array();
      // LI-Elemente durchlaufen und in Array schreiben
      // [0] - Vergleichskriterium
      // [1] - Index in Liste
      // [2] - Clone des Listenelements
      $(this.getElementsByTagName('li')).each(function(i){
        arrLI[i] = [this.innerHTML.toUpperCase(), i, $(this).clone()];
      });

      // Array mit Quicksort sortieren
      quicksort(0, (arrLI.length-1));

      // Fall eine sendende Liste existiert oder das LI-Element innerhalb einer Liste verschoben wurde
      if(ui.sender != null || (document.getElementById(ui.item.parent().attr('id')) == this)){
        // Länge der empfangenden Liste
        var intLen = $(this).find('li').length;
        // Liste neu aufbauen (animiert)
        rebuildList(this, arrLI, intLen-1);
      }
    }
  }).disableSelection();
});

// Liste animiert leeren und neu gefüllt einfaden
function rebuildList(objLI, arrNewLI, intLen){
  // Letztes sichtbares LI ausfaden
  $($(objLI).find('li')[intLen]).fadeOut('slow', function(){
    // Solange das letzte LI noch nicht erreicht wurde -> Funktion rekursiv aufrufen
    if(intLen>0){
      rebuildList(objLI, arrNewLI, intLen-1);
    // Falls das letzte LI ausgeblendet wurde
    }else{
      // Liste transparent machen und anschliessend Callback
      $(objLI).animate({opacity: 0}, 100, function(){
        // Liste leeren
        $(this).empty();
        // Liste mit Clones sortiert füllen
        for(var i=0; i<arrNewLI.length; i++){
          $(objLI).append(arrNewLI[i][2]);
        }
        // Liste wieder einfaden
        $(objLI).animate({opacity: 1}, 'slow');
      });
    }
  });
}

function quicksort(intLower, intUpper){
  var i = intLower, j = intUpper;
  var varHelp = null; //new Array();
  // Teilen des Bereiches und Vergleichswert ermitteln
  var varX = arrLI[parseInt(Math.floor(intLower+intUpper)/2)][0];

  // Teilbereiche bearbeiten bis:
  // - "linker" Bereich enthält alle "kleineren" Werte
  // - "rechter" Bereich enthält alle "grösseren" Werte
  do{
    // Solange Wert im linken Teil kleiner ist -> Grenzeindex inkrementieren
    while(arrLI[i][0] < varX)
      i++;
    // Solange Wert im rechten Teil grösser ist -> Grenzindex dekrementieren
    while(varX < arrLI[j][0])
      j--;

    // Untergrenze kleiner als Obergrenze -> Tausch notwendig
    if(i<=j){
      varHelp = arrLI[i];
      arrLI[i] = arrLI[j];
      arrLI[j] = varHelp;
      i++;
      j--;
    }
  }while(i<j);

  // Quicksort rekursiv aufrufen
  if(intLower < j) quicksort(intLower, j);
  if(i < intUpper) quicksort(i, intUpper);
}