home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1987 / 10 / sort_mod / sorting.imp < prev   
Encoding:
Modula Implementation  |  1987-04-14  |  6.2 KB  |  253 lines

  1.  
  2. IMPLEMENTATION MODULE Sorting;
  3.  
  4.  
  5.   PROCEDURE Swap (VAR a,b : SortType);       (* vertauscht zwei Elemente a,b *)
  6.  
  7.     VAR temp : SortType;
  8.  
  9.     BEGIN
  10.       temp := b;
  11.       b    := a;
  12.       a    := temp;
  13.     END Swap;
  14.  
  15.  
  16. (* ------------  Sortieren nach dem Bubble-Sort-Verfahren  ----------------- *)
  17.  
  18.   PROCEDURE BubbleSort (VAR SortArray  : ARRAY OF SortType;
  19.                             first,last : CARDINAL;
  20.                             Lower      : Comparison;
  21.                             Ascending  : BOOLEAN);
  22.  
  23.     VAR i,top   : CARDINAL;
  24.         swapped : BOOLEAN;
  25.  
  26.  
  27.   (* spezielle Vergleichsfunktion, Berücksichtigung von "Ascending" *)
  28.  
  29.     PROCEDURE lower (VAR a,b : SortType) : BOOLEAN;
  30.  
  31.       BEGIN
  32.         IF Ascending THEN
  33.           RETURN Lower(a,b);
  34.         ELSE
  35.           RETURN Lower(b,a);
  36.         END;
  37.       END lower;
  38.  
  39.  
  40.  (* der Bubble-Sort-Algorithmus *)
  41.  
  42.    BEGIN
  43.       top := last;
  44.       REPEAT
  45.         swapped := FALSE;
  46.         FOR i := first TO top-1 DO
  47.           IF lower (SortArray[i+1],SortArray[i]) THEN
  48.             Swap (SortArray[i],SortArray[i+1]);
  49.             swapped := TRUE;
  50.           END;
  51.         END;
  52.         DEC (top);
  53.       UNTIL NOT swapped;
  54.     END BubbleSort;
  55.  
  56.  
  57.  
  58. (* -------------  Sortieren nach dem Shell-Sort-Verfahren  ----------------- *)
  59.  
  60.   PROCEDURE ShellSort (VAR SortArray  : ARRAY OF SortType;
  61.                            first,last : CARDINAL;
  62.                            Lower      : Comparison;
  63.                            Ascending  : BOOLEAN);
  64.  
  65.     VAR i,j,p : CARDINAL;
  66.  
  67.  
  68.   (* spezielle Vergleichsfunktion, Berücksichtigung von "Ascending" *)
  69.  
  70.     PROCEDURE lower (VAR a,b : SortType) : BOOLEAN;
  71.  
  72.       BEGIN
  73.         IF Ascending THEN
  74.           RETURN Lower(a,b);
  75.         ELSE
  76.           RETURN Lower(b,a);
  77.         END;
  78.       END lower;
  79.  
  80.  
  81.   (* der verfeinerte Shell-Sort-Algorithmus *)
  82.  
  83.     BEGIN
  84.       p := last - first + 1;
  85.       WHILE p > 1 DO
  86.         p := p DIV 2;
  87.         FOR i:=first TO last-p DO
  88.           IF lower(SortArray[i+p],SortArray[i]) THEN
  89.             Swap (SortArray[i],SortArray[i+p]);
  90.             j := i;
  91.             WHILE (j >= first+p) AND lower(SortArray[j],SortArray[j-p]) DO
  92.               Swap (SortArray[j],SortArray[j-p]);
  93.               j := j - p;
  94.             END;
  95.           END;
  96.         END;
  97.       END;
  98.     END ShellSort;
  99.  
  100.  
  101.  
  102. (* -------------  Sortieren nach dem Quick-Sort-Verfahren  ----------------- *)
  103.  
  104.   PROCEDURE QuickSort (VAR SortArray  : ARRAY OF SortType;
  105.                            first,last : CARDINAL;
  106.                            Lower      : Comparison;
  107.                            Ascending  : BOOLEAN);
  108.  
  109.  
  110.   (* spezielle Vergleichsfunktion, Berücksichtigung von "Ascending" *)
  111.  
  112.     PROCEDURE lower (VAR a,b : SortType) : BOOLEAN;
  113.  
  114.       BEGIN
  115.         IF Ascending THEN
  116.           RETURN Lower(a,b);
  117.         ELSE
  118.           RETURN Lower(b,a);
  119.         END;
  120.       END lower;
  121.  
  122.  
  123.   (* Suche nach zwei Elementen mit unterschiedlichen Schlüsseln (a # b) *)
  124.  
  125.     PROCEDURE FindPivot(l,r : CARDINAL) : CARDINAL;
  126.  
  127.       VAR First : SortType;
  128.           Count : CARDINAL;
  129.  
  130.       BEGIN
  131.         First := SortArray[l];
  132.         FOR Count := l+1 TO r DO
  133.           IF lower(SortArray[Count],First) THEN
  134.             RETURN l;
  135.           ELSE
  136.             IF lower(First,SortArray[Count]) THEN
  137.               RETURN Count;
  138.             END;
  139.           END;
  140.         END;
  141.         RETURN 0;
  142.       END FindPivot;
  143.  
  144.  
  145.   (* Ordnen des Teilintervalls l..r, in zwei Intervalle l..p, p+1..r *)
  146.  
  147.     PROCEDURE Permute(l,r : CARDINAL; Pivot : SortType) : CARDINAL;
  148.  
  149.       VAR i,j : CARDINAL;
  150.  
  151.       BEGIN
  152.         i := l;
  153.         j := r;
  154.         REPEAT
  155.           Swap (SortArray[i],SortArray[j]);
  156.           WHILE lower(SortArray[i],Pivot) DO
  157.             INC (i);
  158.           END;
  159.           WHILE NOT lower(SortArray[j],Pivot) DO
  160.             DEC (j);
  161.           END;
  162.         UNTIL (i > j);
  163.         RETURN i;
  164.       END Permute;
  165.  
  166.  
  167.    (* Das Kernstück von Quick-Sort: ein rekursives Sortier-Unterprogramm *)
  168.  
  169.     PROCEDURE DoQuick (Left,Right : CARDINAL);
  170.  
  171.       VAR Index : CARDINAL;
  172.  
  173.       BEGIN
  174.         Index := FindPivot(Left,Right);
  175.         IF Index # 0 THEN
  176.           Index := Permute (Left,Right,SortArray[Index]);
  177.           DoQuick (Left,Index-1);
  178.           DoQuick (Index,Right);
  179.         END;
  180.       END DoQuick;
  181.  
  182.  
  183.    (* das Hauptprogramm besteht lediglich aus einem Einsprung in die rekursi-
  184.                                                           ve Sortier-Routine *)
  185.     BEGIN
  186.       DoQuick (first,last);
  187.     END QuickSort;
  188.  
  189.  
  190.  
  191. (* ---  Sortieren nach dem Shell-Sort-Verfahren durch Index-Permutation ---- *)
  192.  
  193.   PROCEDURE IndexSort (VAR SortArray  : ARRAY OF SortType;
  194.                        VAR Index      : ARRAY OF CARDINAL;  (* das Indexfeld *)
  195.                            first,last : CARDINAL;
  196.                            Lower      : Comparison;
  197.                            Ascending  : BOOLEAN);
  198.  
  199.     VAR i,j,p : CARDINAL;
  200.  
  201.  
  202.   (* spezielle Vergleichsfunktion, Berücksichtigung von "Ascending" *)
  203.  
  204.     PROCEDURE lower (VAR a,b : SortType) : BOOLEAN;
  205.  
  206.       BEGIN
  207.         IF Ascending THEN
  208.           RETURN Lower(a,b);
  209.         ELSE
  210.           RETURN Lower(b,a);
  211.         END;
  212.       END lower;
  213.  
  214.  
  215.     PROCEDURE SwapIndex (VAR i,j : CARDINAL);     (* vertauscht zwei Indizes *)
  216.  
  217.       VAR temp : CARDINAL;
  218.  
  219.       BEGIN
  220.         temp := j;
  221.         j    := i;
  222.         i    := temp;
  223.       END SwapIndex;
  224.  
  225.  
  226.   (* der Shell-Sort-Algorithmus mit Indexvertauschung *)
  227.  
  228.     BEGIN
  229.       FOR i:=first TO last DO                      (* Indizes initialisieren *)
  230.         Index[i] := i;
  231.       END;
  232.       p := last - first + 1;
  233.       WHILE p > 1 DO
  234.         p := p DIV 2;
  235.         FOR i:=first TO last-p DO
  236.           IF lower(SortArray[Index[i+p]],SortArray[Index[i]]) THEN
  237.             SwapIndex (Index[i],Index[i+p]);
  238.             j := i;
  239.             WHILE (j >= first+p) AND lower(SortArray[Index[j]],
  240.                                            SortArray[Index[j-p]]) DO
  241.               SwapIndex (Index[j],Index[j-p]);
  242.               j := j - p;
  243.             END;
  244.           END;
  245.         END;
  246.       END;
  247.     END IndexSort;
  248.  
  249.  
  250.   BEGIN
  251.   (*  keine Initialisierungen notwendig!  *)
  252.   END Sorting.
  253.