Hi,
ich habe in meinem Script-Fundus mal gewühlt(ja, es hat sich einiges angesammelt in den Jahren..) und ein Beispiel für den ShellSort ausgewählt. Vorteil dieses Verfahrens ist, daß es nicht rekursiv arbeitet und(was noch wichtiger ist) es benötigt kein zusätzliches Array. Es kann aufwärts und abwärts sortieren, auch Arrays mit mehreren Spalten, aber seht selbst:
Spoiler anzeigen
#NoTrayIcon
#include "constants.au3"
#include <GUIConstants.au3>
#include <EditConstants.au3>
;<AutoItScript>
Opt("MustDeclareVars", 1) ;0=ohne, 1=erfordert Variablen-Deklaration
;+----------------------------------------------------------------------------+
;| Header: Bestimmen der Übergabeparameter |
;| ( Alles Strings(!!!), bis auf ArgC ) |
;| FontAnzeigeCheck: |Il1 sind Alt-0124, Großes i, Kleines L, Eins |
Const $Autor='ShellSort.au3 ©2008 by ytwinky, MD'; |
;| EMail: [email='PIII1kSystem-AutoIt3Forum@yahoo.de'][/email] |
;| AutoIt3-Version: aktuelle beta |
;| Editor: SciTE aktuelle Version, feste Schriftart |
;| Zweck : Schablone für den Anfang, nach Bedarf anpassen |
;| Tab auf 2 setzen wg. Lesbarkeit |
;+----------------------------------------------------------------------------+
#include <misc.au3>
Const $MaxZeile=15, $MaxSpalte=4, $runter=True
Dim $z, $s, $NachSpalte, $a[$MaxZeile][$MaxSpalte];=[1,11,17,22,37,33,40,42,45,48,56,80,75,95,100]
For $z=0 To $MaxZeile-1
For $s=0 To $MaxSpalte-1
$a[$z][$s]=Random(1, 100, 1)
Next
Next
Do
$NachSpalte=InputBox('Spalten-Nr. eingeben..', 'unten die Spalten-Nr. eintragen, nach der sortiert werden soll', 0)
Until $NachSpalte>=0 And $NachSpalte<=$MaxSpalte
MsgBox(0, "Unsortiert", MkStr($a))
ShellSort($a, 0, $MaxZeile-1, $NachSpalte)
MsgBox(0, "Sortiert(größer)", 'Nach Spalte ' &$NachSpalte &@Lf &MkStr($a, 1))
ShellSort($a, 0, $MaxZeile-1, $NachSpalte, $runter)
MsgBox(0, "Sortiert(kleiner)", 'Nach Spalte ' &$NachSpalte &@Lf &MkStr($a, 1))
Func ShellSort(byRef $a, $aLo, $aHi, $Which, $kleiner=0) ; Sortierrichtung umkehren, wenn<>0
If IsArray($a) Then ;sortieren geht nur, wenn $a ein Array ist, sonst wird nix geändert..
;nach SortDemo.Bas für QBasic 2.0
;Der m$-Shell-Sort funzt mit übergebenen Dimensionen ;-))
Local $i=$aHi-$aLo+1, $li=0, $sw=0, $ig=0, $ik=0, $t, $d
Local $Abstand=Int($i/2) ;Setze den Vergleichsabstand auf die Hälfte der Elemente in A(), schöner wäre $i\2..
While $Abstand>0 ;Schleife bis Abstand=0 ist
$d=-$Abstand
If $kleiner Then $d=0
$li=$aHi-$Abstand
Do
$sw=$aLo ;Erstma keinen Tausch annehmen
For $i=$aLo To $li ;Vergleiche Elemente und tausche die Unsortierten..
$ig=$i+($kleiner<>0)*$Abstand
$ik=$i+$Abstand*($kleiner=0) ;Berechnung nur EINMAL(pro Durchlauf) ausführen..
If $a[$ig][$Which]>$a[$ik][$Which] Then ;hier ändern bei mehrdimensionalen Arrays, sonst nirgends..
SwapLn($a, $ig, $ik)
$sw=$ig ;Schalter setzen
EndIf
Next
$li=$sw-$Abstand ;Sortiere beim nächsten Mal nur bis zum letzten Tausch
Until $sw=$aLo
$Abstand=Int($Abstand/2) ;Kein Tausch beim letzten Mal: Abstand halbieren..
Wend
EndIf
EndFunc ; Vorteil:Keine Rekursion, auch keine Extra-Funktion, kein Extra-Array, kann im Prinzip so eingebaut werden..
Func SwapLn(byRef $a, $g, $k) ;Zeilen vertauschen..
Local $i, $t
For $i=0 To $MaxSpalte-1
$t=$a[$g][$i]
$a[$g][$i]=$a[$k][$i]
$a[$k][$i]=$t
Next
EndFunc
Func MkStr($a, $TestIt=0) ;es ist einfacher eine eigene Funktion zu benutzen..
Local $i, $s='$a ist kein Array..', $j
If IsArray($a) Then
$s=""
For $i=0 To $MaxZeile-1
If $i<10 Then $s&='0'
$s&=StringFormat('%u: ', $i)
For $j=0 To $MaxSpalte-1
$s&=StringFormat('%4u ', $a[$i][$j])
Next
$s&=@Lf
Next
EndIf
Return $s
EndFunc
Viel Spaß beim ShellSortieren
Gruß
ytwinky