|
@@ -3,7 +3,7 @@ MODULE SortDemo; (** AUTHOR "g.f."; PURPOSE sort demo *)
|
|
(* this is an A2-port of the SortDemo done by W.Weck in 1993 for Oberon V4 *)
|
|
(* this is an A2-port of the SortDemo done by W.Weck in 1993 for Oberon V4 *)
|
|
|
|
|
|
IMPORT
|
|
IMPORT
|
|
- Raster, Random, WMRectangles, Strings, WMMessages,
|
|
|
|
|
|
+ Raster, Random, WMRectangles, Strings, WMMessages, WMDialogs,
|
|
WM := WMWindowManager, WMComponents, WMStandardComponents,
|
|
WM := WMWindowManager, WMComponents, WMStandardComponents,
|
|
Log := KernelLog, Clock, Kernel, Machine;
|
|
Log := KernelLog, Clock, Kernel, Machine;
|
|
|
|
|
|
@@ -12,24 +12,30 @@ CONST
|
|
MaxConcurrentSorters = 5; (* assuming we have 6 processor cores *)
|
|
MaxConcurrentSorters = 5; (* assuming we have 6 processor cores *)
|
|
WindowSize = N*ElemSize;
|
|
WindowSize = N*ElemSize;
|
|
|
|
|
|
|
|
+VAR
|
|
|
|
+ compareWeight: LONGINT; (* times move *)
|
|
|
|
+
|
|
TYPE
|
|
TYPE
|
|
- SortData = POINTER TO ARRAY N OF LONGINT;
|
|
|
|
|
|
+ ElementType = LONGINT;
|
|
|
|
+ Index = INTEGER;
|
|
|
|
+ SortData = ARRAY N OF ElementType;
|
|
|
|
|
|
ArrayView* = OBJECT (WM.BufferWindow)
|
|
ArrayView* = OBJECT (WM.BufferWindow)
|
|
VAR
|
|
VAR
|
|
cw: ControlWindow;
|
|
cw: ControlWindow;
|
|
white, grey, col1, yellow: Raster.Pixel;
|
|
white, grey, col1, yellow: Raster.Pixel;
|
|
- data: SortData;
|
|
|
|
|
|
|
|
sortname: ARRAY 32 OF CHAR;
|
|
sortname: ARRAY 32 OF CHAR;
|
|
- random: Random.Generator;
|
|
|
|
delay: LONGINT;
|
|
delay: LONGINT;
|
|
- concSorters: LONGINT;
|
|
|
|
- nofcomps, nofswaps: LONGINT;
|
|
|
|
|
|
+ ha, hb: Index; (* highlighted elements *)
|
|
|
|
+ concurrent: BOOLEAN; concSorters: LONGINT;
|
|
|
|
+ nofcomps, nofswaps, nofmoves: LONGINT;
|
|
|
|
+ timer: Kernel.Timer;
|
|
|
|
+
|
|
|
|
+ data, backup: SortData;
|
|
|
|
|
|
|
|
|
|
PROCEDURE &New( win: ControlWindow );
|
|
PROCEDURE &New( win: ControlWindow );
|
|
- VAR d, t: LONGINT;
|
|
|
|
BEGIN
|
|
BEGIN
|
|
cw := win;
|
|
cw := win;
|
|
Init( WindowSize, WindowSize, FALSE );
|
|
Init( WindowSize, WindowSize, FALSE );
|
|
@@ -41,10 +47,12 @@ TYPE
|
|
Raster.SetRGB( grey, 110, 110, 110 );
|
|
Raster.SetRGB( grey, 110, 110, 110 );
|
|
Raster.SetRGB( col1, 210, 140, 75 );
|
|
Raster.SetRGB( col1, 210, 140, 75 );
|
|
|
|
|
|
- NEW( random ); Clock.Get( t, d ); random.InitSeed( t );
|
|
|
|
- delay := 16;
|
|
|
|
|
|
+ concSorters := 0; concurrent := FALSE;
|
|
|
|
+ delay := 16; NEW( timer );
|
|
|
|
+ compareWeight := 3;
|
|
|
|
|
|
- NEW( data ); OrderData;
|
|
|
|
|
|
+ OrderData; backup :=data;
|
|
|
|
+ Log.String( "SortDemo, weightings: move = 1, swap = 2.5, compare = 3" ); Log.Ln;
|
|
END New;
|
|
END New;
|
|
|
|
|
|
|
|
|
|
@@ -53,22 +61,35 @@ TYPE
|
|
IF x.msgType = WMMessages.MsgClose THEN cw.Close ELSE Handle^( x ) END
|
|
IF x.msgType = WMMessages.MsgClose THEN cw.Close ELSE Handle^( x ) END
|
|
END Handle;
|
|
END Handle;
|
|
|
|
|
|
|
|
+ PROCEDURE Pause;
|
|
|
|
+ VAR t: Kernel.Timer;
|
|
|
|
+ BEGIN
|
|
|
|
+ IF delay > 0 THEN
|
|
|
|
+ IF ~concurrent THEN timer.Sleep( delay )
|
|
|
|
+ ELSE
|
|
|
|
+ NEW( t ); t.Sleep( delay )
|
|
|
|
+ END
|
|
|
|
+ END
|
|
|
|
+ END Pause;
|
|
|
|
|
|
PROCEDURE InitSort;
|
|
PROCEDURE InitSort;
|
|
BEGIN
|
|
BEGIN
|
|
- nofcomps := 0; nofswaps := 0
|
|
|
|
|
|
+ nofcomps := 0; nofswaps := 0; nofmoves := 0;
|
|
|
|
+ backup := data
|
|
END InitSort;
|
|
END InitSort;
|
|
|
|
|
|
PROCEDURE FinishSort;
|
|
PROCEDURE FinishSort;
|
|
BEGIN
|
|
BEGIN
|
|
- Log.String( sortname ); Log.String( ": " );
|
|
|
|
- Log.Int( nofcomps, 1 ); Log.String( " compares, " );
|
|
|
|
- Log.Int( nofswaps, 1 ); Log.String( " swaps, " );
|
|
|
|
- Log.Ln;
|
|
|
|
|
|
+ UnHighlight( ha ); UnHighlight( hb ); Update;
|
|
|
|
+ Log.String( sortname ); Log.String( ": " );
|
|
|
|
+ Log.Int( nofcomps, 1 ); Log.String( " compares, " );
|
|
|
|
+ Log.Int( nofswaps, 1 ); Log.String( " swaps, " );
|
|
|
|
+ Log.Int( nofmoves, 1 ); Log.String( " moves, total effort: " );
|
|
|
|
+ Log.Int( nofcomps*compareWeight + ENTIER(nofswaps*2.5) + nofmoves, 0 ); Log.Ln;
|
|
END FinishSort;
|
|
END FinishSort;
|
|
|
|
|
|
|
|
|
|
- PROCEDURE DrawElement( n: LONGINT );
|
|
|
|
|
|
+ PROCEDURE DrawElement( n: Index );
|
|
VAR mode: Raster.Mode;
|
|
VAR mode: Raster.Mode;
|
|
x, y, len: LONGINT;
|
|
x, y, len: LONGINT;
|
|
BEGIN
|
|
BEGIN
|
|
@@ -85,7 +106,7 @@ TYPE
|
|
END DrawElement;
|
|
END DrawElement;
|
|
|
|
|
|
|
|
|
|
- PROCEDURE Highlight( n: LONGINT );
|
|
|
|
|
|
+ PROCEDURE Highlight( n: Index );
|
|
VAR mode: Raster.Mode;
|
|
VAR mode: Raster.Mode;
|
|
x, y, len: LONGINT;
|
|
x, y, len: LONGINT;
|
|
BEGIN
|
|
BEGIN
|
|
@@ -97,7 +118,7 @@ TYPE
|
|
END;
|
|
END;
|
|
END Highlight;
|
|
END Highlight;
|
|
|
|
|
|
- PROCEDURE Clear( n: LONGINT );
|
|
|
|
|
|
+ PROCEDURE UnHighlight( n: Index );
|
|
VAR mode: Raster.Mode;
|
|
VAR mode: Raster.Mode;
|
|
x, y, len: LONGINT;
|
|
x, y, len: LONGINT;
|
|
BEGIN
|
|
BEGIN
|
|
@@ -107,42 +128,55 @@ TYPE
|
|
IF len > 1 THEN
|
|
IF len > 1 THEN
|
|
Raster.Fill( img, x+1, y+ElemSize+1, x+ElemSize-1, WindowSize, grey, mode )
|
|
Raster.Fill( img, x+1, y+ElemSize+1, x+ElemSize-1, WindowSize, grey, mode )
|
|
END;
|
|
END;
|
|
- END Clear;
|
|
|
|
|
|
+ END UnHighlight;
|
|
|
|
+
|
|
|
|
+ PROCEDURE Highlight2( a, b: Index );
|
|
|
|
+ BEGIN
|
|
|
|
+ IF ~concurrent THEN
|
|
|
|
+ IF (ha # a) & (ha # b) THEN UnHighlight( ha ) END;
|
|
|
|
+ IF (hb # a) & (hb # b) THEN UnHighlight( hb ) END
|
|
|
|
+ END;
|
|
|
|
+ Highlight( a ); Highlight( b );
|
|
|
|
+ ha := a; hb := b
|
|
|
|
+ END Highlight2;
|
|
|
|
|
|
|
|
|
|
PROCEDURE Update;
|
|
PROCEDURE Update;
|
|
BEGIN
|
|
BEGIN
|
|
Invalidate( WMRectangles.MakeRect( 0, 0, GetWidth(), GetHeight() ) );
|
|
Invalidate( WMRectangles.MakeRect( 0, 0, GetWidth(), GetHeight() ) );
|
|
|
|
+ Pause
|
|
END Update;
|
|
END Update;
|
|
|
|
|
|
- PROCEDURE Randomize( n: LONGINT );
|
|
|
|
- VAR i, j, k: LONGINT; t: Kernel.Timer;
|
|
|
|
|
|
+ PROCEDURE Randomize( n: INTEGER );
|
|
|
|
+ VAR i, j, k: Index;
|
|
|
|
+ random: Random.Generator;
|
|
|
|
+ t, d: LONGINT;
|
|
BEGIN
|
|
BEGIN
|
|
- NEW(t);
|
|
|
|
|
|
+ NEW( random ); Clock.Get( t, d ); random.InitSeed( t );
|
|
FOR i := 1 TO n DO
|
|
FOR i := 1 TO n DO
|
|
- j := random.Dice( N ); k := random.Dice( N );
|
|
|
|
|
|
+ j := SHORT( random.Dice( N ) );
|
|
|
|
+ k := SHORT( random.Dice( N ) );
|
|
Swap( j, k );
|
|
Swap( j, k );
|
|
- IF i MOD 16 = 0 THEN t.Sleep(10) END;
|
|
|
|
END
|
|
END
|
|
END Randomize;
|
|
END Randomize;
|
|
|
|
|
|
|
|
|
|
PROCEDURE OrderData;
|
|
PROCEDURE OrderData;
|
|
- VAR i: LONGINT;
|
|
|
|
|
|
+ VAR i: Index;
|
|
BEGIN
|
|
BEGIN
|
|
FOR i := 0 TO N-1 DO data[i] := i + 1; DrawElement( i ) END;
|
|
FOR i := 0 TO N-1 DO data[i] := i + 1; DrawElement( i ) END;
|
|
Update
|
|
Update
|
|
END OrderData;
|
|
END OrderData;
|
|
|
|
|
|
PROCEDURE RevOrderData;
|
|
PROCEDURE RevOrderData;
|
|
- VAR i: LONGINT;
|
|
|
|
|
|
+ VAR i: Index;
|
|
BEGIN
|
|
BEGIN
|
|
FOR i := 0 TO N-1 DO data[i] := N - i; DrawElement( i ) END;
|
|
FOR i := 0 TO N-1 DO data[i] := N - i; DrawElement( i ) END;
|
|
Update
|
|
Update
|
|
END RevOrderData;
|
|
END RevOrderData;
|
|
|
|
|
|
PROCEDURE BadOrder; (* worst case for quicksort *)
|
|
PROCEDURE BadOrder; (* worst case for quicksort *)
|
|
- VAR i, m: LONGINT;
|
|
|
|
|
|
+ VAR i, m: Index;
|
|
BEGIN
|
|
BEGIN
|
|
m := (N - 1) DIV 2;
|
|
m := (N - 1) DIV 2;
|
|
FOR i := 0 TO m-1 DO data[i] := i + 1 END;
|
|
FOR i := 0 TO m-1 DO data[i] := i + 1 END;
|
|
@@ -153,45 +187,52 @@ TYPE
|
|
Update
|
|
Update
|
|
END BadOrder;
|
|
END BadOrder;
|
|
|
|
|
|
- PROCEDURE Swap( i, j: LONGINT );
|
|
|
|
- VAR tmp: LONGINT; t: Kernel.Timer;
|
|
|
|
|
|
+ PROCEDURE LastOrder; (* worst case for quicksort *)
|
|
|
|
+ VAR i: Index;
|
|
BEGIN
|
|
BEGIN
|
|
- IF i # j THEN
|
|
|
|
- tmp := data[i]; data[i] := data[j]; data[j] := tmp;
|
|
|
|
- DrawElement( i ); DrawElement( j );
|
|
|
|
- Update;
|
|
|
|
- IF delay # 0 THEN NEW( t ); t.Sleep( delay ) END;
|
|
|
|
- Machine.AtomicInc( nofswaps )
|
|
|
|
- END
|
|
|
|
- END Swap;
|
|
|
|
|
|
+ data := backup;
|
|
|
|
+ FOR i := 0 TO N-1 DO DrawElement( i ) END;
|
|
|
|
+ Update
|
|
|
|
+ END LastOrder;
|
|
|
|
|
|
- PROCEDURE Less( i, j: LONGINT ): BOOLEAN;
|
|
|
|
- VAR t: Kernel.Timer;
|
|
|
|
- BEGIN
|
|
|
|
- IF delay # 0 THEN
|
|
|
|
- Highlight( i ); Highlight( j ); Update;
|
|
|
|
- NEW( t ); t.Sleep( delay);
|
|
|
|
- Clear( i ); Clear( j ); Update;
|
|
|
|
- END;
|
|
|
|
- Machine.AtomicInc( nofcomps );
|
|
|
|
- RETURN data[i] < data[j];
|
|
|
|
- END Less;
|
|
|
|
|
|
|
|
PROCEDURE DecSpeed;
|
|
PROCEDURE DecSpeed;
|
|
BEGIN
|
|
BEGIN
|
|
IF delay # 0 THEN delay := 2*delay ELSE delay := 4 END;
|
|
IF delay # 0 THEN delay := 2*delay ELSE delay := 4 END;
|
|
- Log.String( "delay: " ); Log.Int( delay, 1 ); Log.Ln
|
|
|
|
|
|
+ Log.String( "delay = " ); Log.Int( delay, 1 ); Log.Ln
|
|
END DecSpeed;
|
|
END DecSpeed;
|
|
|
|
|
|
PROCEDURE IncSpeed;
|
|
PROCEDURE IncSpeed;
|
|
BEGIN
|
|
BEGIN
|
|
IF delay > 4 THEN delay := delay DIV 2 ELSE delay := 0 END;
|
|
IF delay > 4 THEN delay := delay DIV 2 ELSE delay := 0 END;
|
|
- Log.String( "delay: " ); Log.Int( delay, 1 ); Log.Ln
|
|
|
|
|
|
+ Log.String( "delay = " ); Log.Int( delay, 1 ); Log.Ln
|
|
END IncSpeed;
|
|
END IncSpeed;
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
+ PROCEDURE Swap( i, j: Index );
|
|
|
|
+ VAR tmp: LONGINT;
|
|
|
|
+ BEGIN
|
|
|
|
+ IF i # j THEN
|
|
|
|
+ tmp := data[i]; data[i] := data[j]; data[j] := tmp;
|
|
|
|
+ DrawElement( i ); DrawElement( j ); Update;
|
|
|
|
+ Machine.AtomicInc( nofswaps )
|
|
|
|
+ END
|
|
|
|
+ END Swap;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ PROCEDURE Less( i, j: Index ): BOOLEAN;
|
|
|
|
+ BEGIN
|
|
|
|
+ IF delay > 0 THEN
|
|
|
|
+ Highlight2( i, j ); Update;
|
|
|
|
+ END;
|
|
|
|
+ Machine.AtomicInc( nofcomps );
|
|
|
|
+ RETURN data[i] < data[j];
|
|
|
|
+ END Less;
|
|
|
|
+
|
|
|
|
+
|
|
PROCEDURE BubbleSort;
|
|
PROCEDURE BubbleSort;
|
|
- VAR i, n, swaps: LONGINT;
|
|
|
|
|
|
+ VAR i, n: Index; swaps: LONGINT;
|
|
BEGIN
|
|
BEGIN
|
|
sortname := "BubbleSort";
|
|
sortname := "BubbleSort";
|
|
n := N - 2;
|
|
n := N - 2;
|
|
@@ -207,7 +248,7 @@ TYPE
|
|
|
|
|
|
|
|
|
|
PROCEDURE SelectSort;
|
|
PROCEDURE SelectSort;
|
|
- VAR i, j, min: LONGINT;
|
|
|
|
|
|
+ VAR i, j, min: Index;
|
|
BEGIN
|
|
BEGIN
|
|
sortname := "SelectSort";
|
|
sortname := "SelectSort";
|
|
FOR i := 0 TO N-1 DO
|
|
FOR i := 0 TO N-1 DO
|
|
@@ -219,10 +260,10 @@ TYPE
|
|
END
|
|
END
|
|
END SelectSort;
|
|
END SelectSort;
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+
|
|
PROCEDURE ShellSort;
|
|
PROCEDURE ShellSort;
|
|
- VAR i, j, h: LONGINT;
|
|
|
|
|
|
+ VAR i, j, h: Index;
|
|
BEGIN
|
|
BEGIN
|
|
sortname := "ShellSort";
|
|
sortname := "ShellSort";
|
|
i := 4; h := 1;
|
|
i := 4; h := 1;
|
|
@@ -238,7 +279,42 @@ TYPE
|
|
END;
|
|
END;
|
|
END ShellSort;
|
|
END ShellSort;
|
|
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ PROCEDURE Quick( lo, hi: Index; conc: BOOLEAN );
|
|
|
|
+ VAR i, j, m: Index;
|
|
|
|
+ concurrentSorter: ConcurrentQuick;
|
|
|
|
+
|
|
|
|
+ PROCEDURE Inc( VAR i: Index );
|
|
|
|
+ BEGIN
|
|
|
|
+ UnHighlight( i ); INC( i )
|
|
|
|
+ END Inc;
|
|
|
|
+
|
|
|
|
+ PROCEDURE Dec( VAR i: Index );
|
|
|
|
+ BEGIN
|
|
|
|
+ UnHighlight( i ); DEC( i )
|
|
|
|
+ END Dec;
|
|
|
|
+
|
|
|
|
+ BEGIN
|
|
|
|
+ IF lo < hi THEN
|
|
|
|
+ i := lo; j := hi; m := (lo + hi) DIV 2;
|
|
|
|
+ REPEAT
|
|
|
|
+ WHILE Less( i, m ) DO Inc( i ) END; UnHighlight( i );
|
|
|
|
+ WHILE Less( m, j ) DO Dec( j ) END; UnHighlight( j );
|
|
|
|
+ UnHighlight( m );
|
|
|
|
+ IF i <= j THEN
|
|
|
|
+ IF m = i THEN m := j ELSIF m = j THEN m := i END;
|
|
|
|
+ Swap( i, j ); INC( i ); DEC( j )
|
|
|
|
+ END
|
|
|
|
+ UNTIL i > j;
|
|
|
|
+ IF conc & (concSorters < MaxConcurrentSorters) THEN
|
|
|
|
+ NEW( concurrentSorter, SELF, lo, j ); Quick( i, hi, conc )
|
|
|
|
+ ELSE
|
|
|
|
+ Quick( lo, j, conc ); Quick( i, hi, conc )
|
|
|
|
+ END
|
|
|
|
+ END;
|
|
|
|
+ END Quick;
|
|
|
|
+
|
|
|
|
|
|
PROCEDURE QuickSort;
|
|
PROCEDURE QuickSort;
|
|
BEGIN
|
|
BEGIN
|
|
@@ -246,47 +322,93 @@ TYPE
|
|
Quick( 0, N-1, FALSE );
|
|
Quick( 0, N-1, FALSE );
|
|
END QuickSort;
|
|
END QuickSort;
|
|
|
|
|
|
-
|
|
|
|
|
|
+
|
|
PROCEDURE ConcQuickSort;
|
|
PROCEDURE ConcQuickSort;
|
|
VAR t: Kernel.Timer;
|
|
VAR t: Kernel.Timer;
|
|
BEGIN
|
|
BEGIN
|
|
sortname := "QuickSort";
|
|
sortname := "QuickSort";
|
|
- concSorters := 0;
|
|
|
|
|
|
+ concurrent := TRUE; concSorters := 0;
|
|
Quick( 0, N-1, TRUE );
|
|
Quick( 0, N-1, TRUE );
|
|
(* now wait until all concurrent activities have finished *)
|
|
(* now wait until all concurrent activities have finished *)
|
|
- NEW( t ); WHILE concSorters > 0 DO t.Sleep( 50 ) END
|
|
|
|
|
|
+ NEW( t ); WHILE concSorters > 0 DO t.Sleep( 50 ) END;
|
|
|
|
+ concurrent := FALSE;
|
|
END ConcQuickSort;
|
|
END ConcQuickSort;
|
|
|
|
|
|
- PROCEDURE Quick( lo, hi: LONGINT; conc: BOOLEAN );
|
|
|
|
- VAR i, j, m: LONGINT;
|
|
|
|
- concurrentSorter: ConcurrentQuick;
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ PROCEDURE InsertSort( lo, hi: Index );
|
|
|
|
+ VAR x, l, h, m, ip: Index;
|
|
|
|
+
|
|
|
|
+ PROCEDURE Insert; (* insert data[x] at position ip *)
|
|
|
|
+ VAR i: Index; tmp: ElementType;
|
|
|
|
+ BEGIN
|
|
|
|
+ tmp := data[x]; i := x;
|
|
|
|
+ REPEAT data[i] := data[i - 1]; DEC( i ) UNTIL i = ip;
|
|
|
|
+ data[ip] := tmp;
|
|
|
|
+
|
|
|
|
+ INC( nofmoves, x - ip );
|
|
|
|
+ FOR i := ip TO x DO DrawElement( i ) END; Update
|
|
|
|
+ END Insert;
|
|
|
|
+
|
|
|
|
+ BEGIN
|
|
|
|
+ x := lo + 1;
|
|
|
|
+ WHILE x <= hi DO
|
|
|
|
+ IF Less( x, x - 1 ) THEN
|
|
|
|
+ (* find insert position ip *)
|
|
|
|
+ ip := x - 1; l := lo; h := ip - 1;
|
|
|
|
+ WHILE l <= h DO
|
|
|
|
+ m := (l + h) DIV 2;
|
|
|
|
+ IF Less( x, m ) THEN ip := m; h := m - 1 ELSE l := m + 1 END
|
|
|
|
+ END;
|
|
|
|
+ Insert;
|
|
|
|
+ END;
|
|
|
|
+ INC( x )
|
|
|
|
+ END
|
|
|
|
+ END InsertSort;
|
|
|
|
+
|
|
|
|
+ PROCEDURE OptimQuick( lo, hi: Index );
|
|
|
|
+ VAR i, j, m: Index; n: LONGINT;
|
|
BEGIN
|
|
BEGIN
|
|
IF lo < hi THEN
|
|
IF lo < hi THEN
|
|
- i := lo; j := hi; m := (lo + hi) DIV 2;
|
|
|
|
- REPEAT
|
|
|
|
- WHILE Less( i, m ) DO INC( i ) END;
|
|
|
|
- WHILE Less( m, j ) DO DEC( j ) END;
|
|
|
|
- IF i <= j THEN
|
|
|
|
- IF m = i THEN m := j
|
|
|
|
- ELSIF m = j THEN m := i
|
|
|
|
- END;
|
|
|
|
- Swap( i, j ); INC( i ); DEC( j )
|
|
|
|
|
|
+ i := lo; j := hi; m := (lo + hi) DIV 2; n := hi - lo + 1;
|
|
|
|
+ IF n = 2 THEN
|
|
|
|
+ IF Less( hi, lo ) THEN Swap( lo, hi ) END;
|
|
|
|
+ ELSIF n = 3 THEN
|
|
|
|
+ IF Less( m, lo ) THEN Swap( lo, m ) END;
|
|
|
|
+ IF Less( hi, m ) THEN
|
|
|
|
+ Swap( m, hi );
|
|
|
|
+ IF Less( m, lo ) THEN Swap( lo, m ) END
|
|
END
|
|
END
|
|
- UNTIL i > j;
|
|
|
|
- IF conc & (concSorters < MaxConcurrentSorters) THEN
|
|
|
|
- NEW( concurrentSorter, SELF, lo, j ); Quick( i, hi, conc )
|
|
|
|
- ELSE
|
|
|
|
- Quick( lo, j, conc ); Quick( i, hi, conc )
|
|
|
|
|
|
+ ELSIF n < 16 THEN
|
|
|
|
+ InsertSort( lo, hi )
|
|
|
|
+ ELSE (* QuickSort *)
|
|
|
|
+ REPEAT
|
|
|
|
+ WHILE Less( i, m ) DO INC( i ) END;
|
|
|
|
+ WHILE Less( m, j ) DO DEC( j ) END;
|
|
|
|
+ IF i <= j THEN
|
|
|
|
+ IF m = i THEN m := j ELSIF m = j THEN m := i END;
|
|
|
|
+ Swap( i, j ); INC( i ); DEC( j )
|
|
|
|
+ END
|
|
|
|
+ UNTIL i > j;
|
|
|
|
+ OptimQuick( lo, j ); OptimQuick( i, hi )
|
|
END
|
|
END
|
|
END;
|
|
END;
|
|
- END Quick;
|
|
|
|
-
|
|
|
|
|
|
+ END OptimQuick;
|
|
|
|
|
|
|
|
+ PROCEDURE OptimQuickSort;
|
|
|
|
+ BEGIN
|
|
|
|
+ sortname := "Optim. QuickSort";
|
|
|
|
+ OptimQuick( 0, N - 1 );
|
|
|
|
+ END OptimQuickSort;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
PROCEDURE HeapSort;
|
|
PROCEDURE HeapSort;
|
|
- VAR l, r: LONGINT;
|
|
|
|
|
|
+ VAR l, r: Index;
|
|
|
|
|
|
- PROCEDURE Sift( l, r: LONGINT );
|
|
|
|
- VAR i, j: LONGINT;
|
|
|
|
|
|
+ PROCEDURE Sift( l, r: Index );
|
|
|
|
+ VAR i, j: Index;
|
|
BEGIN
|
|
BEGIN
|
|
i := l; j := 2*l + 1;
|
|
i := l; j := 2*l + 1;
|
|
IF (j + 1 < r) & Less( j, j + 1 ) THEN INC( j ) END;
|
|
IF (j + 1 < r) & Less( j, j + 1 ) THEN INC( j ) END;
|
|
@@ -307,20 +429,20 @@ TYPE
|
|
|
|
|
|
|
|
|
|
PROCEDURE SmoothSort; (* W.Weck 21 Jan 93, SmoothSort due to E.W.Dijkstra, J.Gutknecht *)
|
|
PROCEDURE SmoothSort; (* W.Weck 21 Jan 93, SmoothSort due to E.W.Dijkstra, J.Gutknecht *)
|
|
- VAR q, r, p, b, c: LONGINT;
|
|
|
|
|
|
+ VAR q, r, p, b, c: Index;
|
|
|
|
|
|
- PROCEDURE up( VAR b, c: LONGINT );
|
|
|
|
- VAR b1: LONGINT;
|
|
|
|
|
|
+ PROCEDURE up( VAR b, c: Index );
|
|
|
|
+ VAR b1: Index;
|
|
BEGIN b1 := b; b := b + c + 1; c := b1
|
|
BEGIN b1 := b; b := b + c + 1; c := b1
|
|
END up;
|
|
END up;
|
|
|
|
|
|
- PROCEDURE down( VAR b, c: LONGINT );
|
|
|
|
- VAR c1: LONGINT;
|
|
|
|
|
|
+ PROCEDURE down( VAR b, c: Index );
|
|
|
|
+ VAR c1: Index;
|
|
BEGIN c1 := c; c := b - c - 1; b := c1
|
|
BEGIN c1 := c; c := b - c - 1; b := c1
|
|
END down;
|
|
END down;
|
|
|
|
|
|
- PROCEDURE sift( r, b, c: LONGINT );
|
|
|
|
- VAR r1: LONGINT;
|
|
|
|
|
|
+ PROCEDURE sift( r, b, c: Index );
|
|
|
|
+ VAR r1: Index;
|
|
BEGIN
|
|
BEGIN
|
|
WHILE b >= 3 DO r1 := r - b + c;
|
|
WHILE b >= 3 DO r1 := r - b + c;
|
|
IF Less( r1, r - 1 ) THEN r1 := r - 1; down( b, c ) END;
|
|
IF Less( r1, r - 1 ) THEN r1 := r - 1; down( b, c ) END;
|
|
@@ -328,8 +450,8 @@ TYPE
|
|
END
|
|
END
|
|
END sift;
|
|
END sift;
|
|
|
|
|
|
- PROCEDURE trinkle( r, p, b, c: LONGINT );
|
|
|
|
- VAR r1, r2: LONGINT;
|
|
|
|
|
|
+ PROCEDURE trinkle( r, p, b, c: Index );
|
|
|
|
+ VAR r1, r2: Index;
|
|
BEGIN
|
|
BEGIN
|
|
WHILE p > 0 DO
|
|
WHILE p > 0 DO
|
|
WHILE ~ODD( p ) DO p := p DIV 2; up( b, c ) END;
|
|
WHILE ~ODD( p ) DO p := p DIV 2; up( b, c ) END;
|
|
@@ -346,8 +468,8 @@ TYPE
|
|
sift( r, b, c )
|
|
sift( r, b, c )
|
|
END trinkle;
|
|
END trinkle;
|
|
|
|
|
|
- PROCEDURE semiTrinkle( r, p, b, c: LONGINT );
|
|
|
|
- VAR r1: LONGINT;
|
|
|
|
|
|
+ PROCEDURE semiTrinkle( r, p, b, c: Index );
|
|
|
|
+ VAR r1: Index;
|
|
BEGIN r1 := r - c;
|
|
BEGIN r1 := r - c;
|
|
IF Less( r, r1 ) THEN Swap( r, r1 ); trinkle( r1, p, b, c ) END
|
|
IF Less( r, r1 ) THEN Swap( r, r1 ); trinkle( r1, p, b, c ) END
|
|
END semiTrinkle;
|
|
END semiTrinkle;
|
|
@@ -383,10 +505,10 @@ TYPE
|
|
|
|
|
|
ConcurrentQuick = OBJECT
|
|
ConcurrentQuick = OBJECT
|
|
VAR
|
|
VAR
|
|
- lo, hi: LONGINT;
|
|
|
|
|
|
+ lo, hi: Index;
|
|
av: ArrayView;
|
|
av: ArrayView;
|
|
|
|
|
|
- PROCEDURE &Init ( sdw: ArrayView; low, high: LONGINT );
|
|
|
|
|
|
+ PROCEDURE &Init ( sdw: ArrayView; low, high: Index );
|
|
BEGIN
|
|
BEGIN
|
|
av := sdw;
|
|
av := sdw;
|
|
lo := low; hi := high;
|
|
lo := low; hi := high;
|
|
@@ -489,7 +611,7 @@ TYPE
|
|
toolbar.fillColor.Set( LONGINT( 0CCCCCCFFH ) );
|
|
toolbar.fillColor.Set( LONGINT( 0CCCCCCFFH ) );
|
|
|
|
|
|
NEW( label );
|
|
NEW( label );
|
|
- label.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ label.bounds.SetWidth( 70 );
|
|
label.alignment.Set( WMComponents.AlignLeft );
|
|
label.alignment.Set( WMComponents.AlignLeft );
|
|
label.caption.SetAOC( " Array init: " );
|
|
label.caption.SetAOC( " Array init: " );
|
|
label.textColor.Set( 0000000FFH );
|
|
label.textColor.Set( 0000000FFH );
|
|
@@ -497,43 +619,49 @@ TYPE
|
|
|
|
|
|
|
|
|
|
NEW( button );
|
|
NEW( button );
|
|
- button.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ button.bounds.SetWidth( 70 );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.caption.SetAOC( " order " );
|
|
button.caption.SetAOC( " order " );
|
|
button.onClick.Add( Order );
|
|
button.onClick.Add( Order );
|
|
toolbar.AddContent( button );
|
|
toolbar.AddContent( button );
|
|
|
|
|
|
NEW( button );
|
|
NEW( button );
|
|
- button.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ button.bounds.SetWidth( 70 );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.caption.SetAOC( " rev. order " );
|
|
button.caption.SetAOC( " rev. order " );
|
|
button.onClick.Add( RevOrder );
|
|
button.onClick.Add( RevOrder );
|
|
toolbar.AddContent( button );
|
|
toolbar.AddContent( button );
|
|
|
|
|
|
NEW( button );
|
|
NEW( button );
|
|
- button.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ button.bounds.SetWidth( 70 );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
- button.caption.SetAOC( " bad order " );
|
|
|
|
|
|
+ button.caption.SetAOC( "bad order" );
|
|
button.onClick.Add( BadOrder );
|
|
button.onClick.Add( BadOrder );
|
|
toolbar.AddContent( button );
|
|
toolbar.AddContent( button );
|
|
|
|
|
|
-
|
|
|
|
NEW( button );
|
|
NEW( button );
|
|
- button.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ button.bounds.SetWidth( 70 );
|
|
|
|
+ button.alignment.Set( WMComponents.AlignLeft );
|
|
|
|
+ button.caption.SetAOC( "last order" );
|
|
|
|
+ button.onClick.Add( LastOrder );
|
|
|
|
+ toolbar.AddContent( button );
|
|
|
|
+
|
|
|
|
+ NEW( button );
|
|
|
|
+ button.bounds.SetWidth( 70 );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.caption.SetAOC( " rand 10 " );
|
|
button.caption.SetAOC( " rand 10 " );
|
|
button.onClick.Add( Rand10 );
|
|
button.onClick.Add( Rand10 );
|
|
toolbar.AddContent( button );
|
|
toolbar.AddContent( button );
|
|
|
|
|
|
NEW( button );
|
|
NEW( button );
|
|
- button.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ button.bounds.SetWidth( 70 );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.caption.SetAOC( " rand 100 " );
|
|
button.caption.SetAOC( " rand 100 " );
|
|
button.onClick.Add( Rand100 );
|
|
button.onClick.Add( Rand100 );
|
|
toolbar.AddContent( button );
|
|
toolbar.AddContent( button );
|
|
|
|
|
|
NEW( button );
|
|
NEW( button );
|
|
- button.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ button.bounds.SetWidth( 70 );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.caption.SetAOC( " rand 200 " );
|
|
button.caption.SetAOC( " rand 200 " );
|
|
button.onClick.Add( Rand200 );
|
|
button.onClick.Add( Rand200 );
|
|
@@ -547,7 +675,7 @@ TYPE
|
|
toolbar.fillColor.Set( LONGINT( 0CCCCCCFFH ) );
|
|
toolbar.fillColor.Set( LONGINT( 0CCCCCCFFH ) );
|
|
|
|
|
|
NEW( label );
|
|
NEW( label );
|
|
- label.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ label.bounds.SetWidth( 70 );
|
|
label.alignment.Set( WMComponents.AlignLeft );
|
|
label.alignment.Set( WMComponents.AlignLeft );
|
|
label.caption.SetAOC( " Sorter: " );
|
|
label.caption.SetAOC( " Sorter: " );
|
|
label.textColor.Set( 0000000FFH );
|
|
label.textColor.Set( 0000000FFH );
|
|
@@ -576,7 +704,7 @@ TYPE
|
|
toolbar.AddContent( button );
|
|
toolbar.AddContent( button );
|
|
|
|
|
|
NEW( button );
|
|
NEW( button );
|
|
- button.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ button.bounds.SetWidth( 90 );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.caption.SetAOC( " Quick " );
|
|
button.caption.SetAOC( " Quick " );
|
|
button.onClick.Add( StartQuickSort );
|
|
button.onClick.Add( StartQuickSort );
|
|
@@ -605,7 +733,7 @@ TYPE
|
|
toolbar.fillColor.Set( LONGINT( 0CCCCCCFFH ) );
|
|
toolbar.fillColor.Set( LONGINT( 0CCCCCCFFH ) );
|
|
|
|
|
|
NEW( label );
|
|
NEW( label );
|
|
- label.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ label.bounds.SetWidth( 70 );
|
|
label.alignment.Set( WMComponents.AlignLeft );
|
|
label.alignment.Set( WMComponents.AlignLeft );
|
|
label.caption.SetAOC( " Speed: " );
|
|
label.caption.SetAOC( " Speed: " );
|
|
label.textColor.Set( 0000000FFH );
|
|
label.textColor.Set( 0000000FFH );
|
|
@@ -613,7 +741,7 @@ TYPE
|
|
|
|
|
|
|
|
|
|
NEW( button );
|
|
NEW( button );
|
|
- button.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ button.bounds.SetWidth( 40 );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.caption.SetAOC( " - " );
|
|
button.caption.SetAOC( " - " );
|
|
button.onClick.Add( DecSpeed );
|
|
button.onClick.Add( DecSpeed );
|
|
@@ -621,25 +749,38 @@ TYPE
|
|
|
|
|
|
|
|
|
|
NEW( button );
|
|
NEW( button );
|
|
- button.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ button.bounds.SetWidth( 40 );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.caption.SetAOC( " + " );
|
|
button.caption.SetAOC( " + " );
|
|
button.onClick.Add( IncSpeed );
|
|
button.onClick.Add( IncSpeed );
|
|
toolbar.AddContent( button );
|
|
toolbar.AddContent( button );
|
|
|
|
+
|
|
|
|
+ NEW( button );
|
|
|
|
+ button.bounds.SetWidth( 120 );
|
|
|
|
+ button.alignment.Set( WMComponents.AlignLeft );
|
|
|
|
+ button.caption.SetAOC( "adj. comp. weight" );
|
|
|
|
+ button.onClick.Add( SetCompareWeight );
|
|
|
|
+ toolbar.AddContent( button );
|
|
|
|
|
|
NEW( label );
|
|
NEW( label );
|
|
- label.bounds.SetWidth( 80 );
|
|
|
|
|
|
+ label.bounds.SetWidth( 40 );
|
|
label.alignment.Set( WMComponents.AlignLeft );
|
|
label.alignment.Set( WMComponents.AlignLeft );
|
|
label.textColor.Set( 0000000FFH );
|
|
label.textColor.Set( 0000000FFH );
|
|
toolbar.AddContent(label);
|
|
toolbar.AddContent(label);
|
|
-
|
|
|
|
|
|
+
|
|
NEW( button );
|
|
NEW( button );
|
|
- button.bounds.SetWidth( 160 );
|
|
|
|
|
|
+ button.bounds.SetWidth( 125 );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.alignment.Set( WMComponents.AlignLeft );
|
|
button.caption.SetAOC( " concurrent Quick " );
|
|
button.caption.SetAOC( " concurrent Quick " );
|
|
button.onClick.Add( StartConcQuickSort );
|
|
button.onClick.Add( StartConcQuickSort );
|
|
toolbar.AddContent( button );
|
|
toolbar.AddContent( button );
|
|
|
|
|
|
|
|
+ NEW( button );
|
|
|
|
+ button.bounds.SetWidth( 125 );
|
|
|
|
+ button.alignment.Set( WMComponents.AlignLeft );
|
|
|
|
+ button.caption.SetAOC( " optim. Quick " );
|
|
|
|
+ button.onClick.Add( StartOptimQuickSort );
|
|
|
|
+ toolbar.AddContent( button );
|
|
|
|
|
|
panel.AddContent( toolbar );
|
|
panel.AddContent( toolbar );
|
|
|
|
|
|
@@ -661,6 +802,11 @@ TYPE
|
|
IF ~ sorter.running THEN av.BadOrder END
|
|
IF ~ sorter.running THEN av.BadOrder END
|
|
END BadOrder;
|
|
END BadOrder;
|
|
|
|
|
|
|
|
+ PROCEDURE LastOrder( sender, data: ANY );
|
|
|
|
+ BEGIN
|
|
|
|
+ IF ~ sorter.running THEN av.LastOrder END
|
|
|
|
+ END LastOrder;
|
|
|
|
+
|
|
|
|
|
|
PROCEDURE Rand10( sender, data: ANY );
|
|
PROCEDURE Rand10( sender, data: ANY );
|
|
BEGIN
|
|
BEGIN
|
|
@@ -688,7 +834,16 @@ TYPE
|
|
av.DecSpeed
|
|
av.DecSpeed
|
|
END DecSpeed;
|
|
END DecSpeed;
|
|
|
|
|
|
-
|
|
|
|
|
|
+ PROCEDURE SetCompareWeight( sender, data: ANY );
|
|
|
|
+ VAR digits: ARRAY 8 OF CHAR;
|
|
|
|
+ BEGIN
|
|
|
|
+ digits := "3";
|
|
|
|
+ IF WMDialogs.QueryString( "Input compare weight", digits ) = 0 THEN
|
|
|
|
+ Strings.StrToInt( digits, compareWeight );
|
|
|
|
+ Log.String( "new weightings: move = 1, swap = 2.5, compare = " );
|
|
|
|
+ Log.Int( compareWeight, 1 ); Log.Ln;
|
|
|
|
+ END
|
|
|
|
+ END SetCompareWeight;
|
|
|
|
|
|
PROCEDURE StartBubbleSort( sender, data: ANY );
|
|
PROCEDURE StartBubbleSort( sender, data: ANY );
|
|
BEGIN
|
|
BEGIN
|
|
@@ -702,6 +857,11 @@ TYPE
|
|
END StartSelectSort;
|
|
END StartSelectSort;
|
|
|
|
|
|
|
|
|
|
|
|
+ PROCEDURE StartOptimQuickSort( sender, data: ANY );
|
|
|
|
+ BEGIN
|
|
|
|
+ sorter.Start( av.OptimQuickSort )
|
|
|
|
+ END StartOptimQuickSort;
|
|
|
|
+
|
|
PROCEDURE StartShellSort( sender, data: ANY );
|
|
PROCEDURE StartShellSort( sender, data: ANY );
|
|
BEGIN
|
|
BEGIN
|
|
sorter.Start( av.ShellSort )
|
|
sorter.Start( av.ShellSort )
|