Advertisement
Guest User

Anton's Quicksort with kinematic partitioning

a guest
Oct 14th, 2017
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (* ----------------- Quicksort with Kinematic partitioning ----------------- *)
  2. (*                         ( by Anton Shepelev )                             *)
  3. IMPLEMENTATION MODULE KineSort;
  4. FROM SYSTEM IMPORT ADDRESS;
  5.  
  6. PROCEDURE Partition
  7.   ( data: ADDRESS; left, right: INTEGER; VAR op: SortOps ):INTEGER;
  8. VAR
  9.   midInd, l, r:     INTEGER;
  10.   lFit, rFit, bump: BOOLEAN;
  11.   term:             INTEGER;
  12. BEGIN
  13.   bump := FALSE;
  14.   (* The confluent case of a two-element array.                         *)
  15.   (* To save one level on invocation, handle this condittion in Sort(): *)
  16.   IF right - left = 1 THEN
  17.     IF op.Comp( data, right, left ) < 0 THEN op.Swap( data, left, right ); END;
  18.     RETURN left;
  19.   END;
  20.  
  21.   midInd := (left + right) DIV 2;
  22.   op.Swap( data, left, midInd ); (* fix pivot location for easy access *)
  23.   r := right + 1 ; l := left + 1 - 1;
  24.  
  25.   LOOP
  26.     lFit := TRUE; rFit:= TRUE;
  27.  
  28.     LOOP
  29.      
  30.       IF lFit THEN
  31.         INC( l );
  32.         lFit := op.Comp( data, l, left ) <= 0;
  33.         IF r - l = 1 THEN bump := TRUE; EXIT; END;
  34.       END;
  35.      
  36.       IF rFit THEN
  37.         DEC( r );
  38.         rFit := op.Comp( data, r, left ) >= 0;
  39.         IF r - l = 1 THEN bump := TRUE; EXIT; END;
  40.       END;
  41.      
  42.       IF NOT ( lFit OR rFit ) THEN EXIT; END;
  43.      
  44.     END;
  45.    
  46.     (* for lack of bitwise operations *)
  47.     IF lFit THEN term := 2 ELSE term := 0; END;
  48.     IF rFit THEN INC( term ); END;
  49.    
  50.     (* nested CASE would be too cumbersome *)
  51.     CASE term OF
  52.       0: op.Swap( data, l, r );
  53.          IF bump THEN RETURN l; END;          |
  54.       1: op.Swap( data, l, r ); RETURN l - 1; |
  55.       2: IF r = right THEN
  56.            op.Swap( data, left, r );
  57.            RETURN l;
  58.          ELSE RETURN r;
  59.          END;                                 |
  60.       3: RETURN l;
  61.     END;
  62.   END;
  63.  
  64. END Partition;
  65.  
  66. PROCEDURE Sort
  67.   ( data: ADDRESS; left: INTEGER; right: INTEGER; VAR op: SortOps );
  68. VAR middle: INTEGER;
  69. BEGIN
  70.   middle := Partition( data, left, right, op );    
  71.   IF middle > left  THEN Sort( data, left,   middle, op ); END;
  72.   INC( middle );
  73.   IF middle < right THEN Sort( data, middle, right,  op ); END;
  74. END Sort;
  75.  
  76. END KineSort.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement