ShakerSort

  • Hey Leute

    ich versuche gerade einen Sortieralgorithmus namens Shakersort zu schreiben, aber ich bekomme einen Fehler wo ich keinen sehe.

    ich hoffe ihr könnt mir helfen.

    Danke

    DFPWare


    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    Dim $Feld[100]
    Dim $neuesFeld[100]
    For $i = 0 To 99 Step 1
    $Feld[$i] = Random(1, 1000, 1)
    Next
    _ArrayDisplay($Feld)
    $neuesFeld = _ShakerSort($Feld)
    _ArrayDisplay($neuesFeld)
    #cs
    _ShakerSort
    Der Array wird zu Erst von vorne nach hinten durchsucht und ausgetauscht, wie bei BubbleSort, aber nur einmal.
    Dann wird der Array von hinten nach vorne durchsucht und ausgetauscht.
    Danach ist die größte Zahl hinten und die kleinste Zahl vorne.
    Dadurch müssen das erste und letzte Feld nicht mehr untersucht werden.
    Das wird wiederholt und dann sind die beiden größten Zahlen hinten und die beiden kleinsten Zahlen vorne.
    Das wird solange wiederholt, bis sich die beiden Fronten in der Mitte treffen.
    Dann ist der Array sortiert.
    Ein ähnliches Verfahren namens Selectsort funktioniert genauso, jedoch wird immer von vorne nach hinten durchsucht und immer nur das letzte Feld abgeschnitten.
    #ce
    Func _ShakerSort($iArray)
    If UBound($iArray,0) <> 1 Then
    MsgBox(0,"ERROR","Sie haben keinen eindimensionalen Array angegeben")
    Exit
    EndIf
    $links = 0
    $rechts = UBound($iArray,1)
    Do
    $iArray = _ShakerLinks($iArray,$links,$rechts)
    $links -= 1
    $iArray = _ShakerRechts($iArray,$links,$rechts)
    $rechts -= 1
    Until $links > $rechts
    EndFunc
    Func _ShakerLinks($lArray,$l,$r)
    For $i=$l To $r-1 Step 1
    ConsoleWrite($i&@CRLF)
    If $lArray[$i] > $lArray[$i + 1] Then
    _ArraySwap($lArray[$i + 1], $lArray[$i])
    EndIf
    Next
    Return $lArray
    EndFunc
    Func _ShakerRechts($rArray,$l,$r)
    For $i = $r-1 To $l Step 1
    If $rArray[$i] < $rArray[$i - 1] Then
    _ArraySwap($rArray[$i - 1], $rArray[$i])
    EndIf
    Next
    Return $rArray
    EndFunc

    [/autoit]
  • Das sind mehre Probleme und Fehler.

    - Du lässt den For schleife von 0 bis 100 laufen obwohl der Array nur bis index 99 geht.
    - Der index startet nach dem ersten durchlauf wegen $links -= 1 im negativen Bereich
    - Der Index landet wegen $i -1 im nagativen Bereich

    da sind denke ich noch mehr solche Sachen drin, hab aber dann aufgehört weiter zu suchen. Am besten nochmal löschen und neu machen :).

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • Hast du das Skript ausgeführt?

    Bei mir wird das Programm schon vor Beendigung von _ShakerLinks beendet.

    Code
    C:\Users\XXXXXX\Desktop\AutoIt v3 Script (neu).au3 (42) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.: 
    If $lArray[$i] > $lArray[$i + 1] Then 
    If $lArray[$i] > ^ ERROR 
    ->10:18:13 AutoIT3.exe ended.rc:1 
    >Exit code: 1 Time: 2.752

    1.) die For-Schleife läuft nicht bis 100, sie läuft bis $r-1, $r = $rechts aus _ShakerSort, $rechts ist Ubound($iArray), Ubound($iArray) ist 100;

    ==>> sie läuft bis 100-1 ==>> 99

    2.) stimmt es müsste so heißen:

    [autoit]

    $links += 1

    [/autoit]

    3.) wenn ich das richtig verstanden hab dann ist das damit ^ behoben


    Es funktioniert aber immer noch nicht, der Fehler bleibt der Selbe

  • habs doch selber hinbekommen ;)

    für alle die es interessiert hier das Skript:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    Dim $Feld[100]
    Dim $neuesFeld[100]
    For $i = 0 To 99 Step 1
    $Feld[$i] = Random(1, 1000, 1)
    Next
    _ArrayDisplay($Feld)
    $neuesFeld = _ShakerSort($Feld)
    _ArrayDisplay($neuesFeld)
    #cs
    _ShakerSort
    Der Array wird zu Erst von vorne nach hinten durchsucht und ausgetauscht, wie bei BubbleSort, aber nur einmal.
    Dann wird der Array von hinten nach vorne durchsucht und ausgetauscht.
    Danach ist die größte Zahl hinten und die kleinste Zahl vorne.
    Dadurch müssen das erste und letzte Feld nicht mehr untersucht werden.
    Das wird wiederholt und dann sind die beiden größten Zahlen hinten und die beiden kleinsten Zahlen vorne.
    Das wird solange wiederholt, bis sich die beiden Fronten in der Mitte treffen.
    Dann ist der Array sortiert.
    Ein ähnliches Verfahren namens Selectsort funktioniert genauso, jedoch wird immer von vorne nach hinten durchsucht und immer nur das letzte Feld abgeschnitten.
    #ce
    Func _ShakerSort($iArray)
    If UBound($iArray,0) <> 1 Then
    MsgBox(0,"ERROR","Sie haben keinen eindimensionalen Array angegeben")
    Exit
    EndIf
    $links = 0
    $rechts = UBound($iArray,1)-1
    Do
    $iArray = _ShakerLinks($iArray,$links,$rechts)
    $links += 1
    $iArray = _ShakerRechts($iArray,$links,$rechts)
    $rechts -= 1
    Until $links > $rechts
    Return $iArray
    EndFunc
    Func _ShakerLinks($lArray,$l,$r)
    For $i=$l To $r-1 Step 1
    If $lArray[$i] > $lArray[$i + 1] Then
    _ArraySwap($lArray[$i + 1], $lArray[$i])
    EndIf
    Next
    Return $lArray
    EndFunc
    Func _ShakerRechts($rArray,$l,$r)
    For $i = $r-1 To $l Step -1
    If $rArray[$i] < $rArray[$i - 1] Then
    _ArraySwap($rArray[$i - 1], $rArray[$i])
    EndIf
    Next
    Return $rArray
    EndFunc

    [/autoit]