[M3devel] Dual Pivot Quicksort problem (FIXED)

Martin Bishop mbishop at esoteriq.org
Sat Sep 12 06:12:17 CEST 2009


Sorry to keep posting, but I just wanted to say I fixed the problem (it 
isn't even in this code, it was in the insertion sort module.)

Martin Bishop wrote:
> Edited it some more, lots of silly mistakes in that old code.  Now it 
> almost works...it sorts the array sometimes, but other times gives me 
> a bounds error.  Any idea now?
>
> MODULE DualPivot;
>
> IMPORT Insertion, Fmt, IO;
>
> PROCEDURE Sort(VAR arr: ARRAY OF INTEGER) =
>  BEGIN
>    SortFromTo(arr, 0, NUMBER(arr));
>  END Sort;
>
> PROCEDURE SortFromTo(VAR arr: ARRAY OF INTEGER; from, to: INTEGER) =
>  BEGIN
>    RangeCheck(NUMBER(arr), from, to);
>    DualPivotSort(arr, from, to - 1, 3);
>  END SortFromTo;
>
> PROCEDURE RangeCheck(len, from, to: INTEGER) RAISES {BadArgument, 
> IndexOutOfRange} =
>  BEGIN
>    IF from > to THEN
>      RAISE BadArgument(Fmt.Int(from) & " > " & Fmt.Int(to) & "\n");
>    END;
>    IF from < 0 THEN
>      RAISE IndexOutOfRange("from");
>    END;
>    IF to > len THEN
>      RAISE IndexOutOfRange("to");
>    END;
>  END RangeCheck;
>
> PROCEDURE Swap(VAR arr: ARRAY OF INTEGER; i, j: INTEGER) =
>  VAR temp := arr[i];
>  BEGIN
>    arr[i] := arr[j];
>    arr[j] := temp;
>  END Swap;
>
> PROCEDURE DualPivotSort(VAR arr: ARRAY OF INTEGER; left, right, div: 
> INTEGER) =
>  VAR
>    len := right - left;
>    third := len DIV div;
>    m1 := left + third;
>    m2 := right - third;
>    piv1: INTEGER;
>    piv2: INTEGER;
>    less := left + 1;
>    great := right - 1;
>    dist: INTEGER;
>
>  BEGIN
>    IF len < 27 THEN
>      Insertion.Sort(arr);
>      RETURN;
>    END;
>
>    IF m1 <= left THEN
>      m1 := left + 1;
>    END;
>
>    IF m2 >= right THEN
>      m2 := right - 1;
>    END;
>
>    IO.Put("DEBUG: m1 = " & Fmt.Int(m1) & " m2 = " & Fmt.Int(m2) &
>      " left = " & Fmt.Int(left) & " right = " & Fmt.Int(right) & "\n");
>    IO.Put("DEBUG: len = " & Fmt.Int(len) & " third = " & 
> Fmt.Int(third) & "\n");
>    IO.Put("***\n");
>
>    IF arr[m1] < arr[m2] THEN
>      Swap(arr, m1, left);
>      Swap(arr, m2, right);
>    ELSE
>      Swap(arr, m1, right);
>      Swap(arr, m2, left);
>    END;
>
>    piv1 := arr[left];
>    piv2 := arr[right];
>      FOR k := less TO great DO
>      IF arr[k] < piv1 THEN
>        Swap(arr, k, less);
>        INC(less);
>      ELSIF arr[k] > piv2 THEN
>        WHILE (k < great) AND (arr[great] > piv2) DO
>          DEC(great);
>        END;
>        Swap(arr, k, great);
>        DEC(great);
>              IF arr[k] < piv1 THEN
>          Swap(arr, k, less);
>          INC(less);
>        END;
>      END;
>    END;
>
>    dist := great - less;
>
>    IF dist < 13 THEN
>      INC(div);
>    END;
>
>    Swap(arr, less - 1, left);
>    Swap(arr, great + 1, right);
>      DualPivotSort(arr, left, less - 2, div);
>    DualPivotSort(arr, great + 2, right, div);
>      IF (dist > len - 13) AND (piv1 # piv2) THEN
>      FOR k := less TO great DO
>        IF arr[k] = piv1 THEN
>          Swap(arr, k, less);
>          INC(less);
>        ELSIF arr[k] = piv2 THEN
>          Swap(arr, k, great);
>          DEC(great);
>                  IF arr[k] = piv1 THEN
>            Swap(arr, k, less);
>            INC(less);
>          END;
>        END;
>      END;
>    END;
>
>    IF piv1 < piv2 THEN
>      DualPivotSort(arr, less, great, div);
>    END;
>  END DualPivotSort;
>
> BEGIN
> END DualPivot.
>
> Martin Bishop wrote:
>> I saw a post on reddit about a Dual Pivot Quicksort, and I translated 
>> the code from Java to Modula-3.  I have it all translated, and it 
>> builds, but I am having boundary issues.  Somewhere on the second 
>> pass, the variable m2 is getting the value -2.  Here's the code:
>>
>> ...
>
>> Right now when I try to run I get:
>>
>> ***
>> *** runtime error:
>> ***    An array subscript was out of range.
>> ***    file "../DualPivot.m3", line 61
>> ***
>>
>> Line 61 is:  IF arr[m1] < arr[m2] THEN
>>
>> Anyone see what is happening? It's probably off by 1 (or more) 
>> errors, but I don't see them.
>>
>>
>
>




More information about the M3devel mailing list