Вы находитесь на странице: 1из 19

Source code này minh hoạ cách dùng 5 thuật toán sắp xếp cơ bản:

1. SELECTION SORT
2. INSERTION SORT
3. BUBBLE SORT
4. QUICK SORT
5. MERGE SORT

Post lên đây cho các bạn tham khảo. 

{
This program demos various sorting algorithms, which includes:

      1. Selection Sort

      2. Insertion Sort

      3. Bubble Sort

      4. Quick Sort

      5. Merge Sort

      Written by Ha Minh Nam, Hanoi, Sep 2004


}

Program Sorting_Algorithm;
Uses Crt;
Const f_in='INPUT.TXT';
      f_out='OUTPUT.TXT';
Var arrValue, arrTmp, arrZ:Array[0..99] of Integer;
    F:Text;
    TotalElement: Integer;
{-------------------------------Begin Init---------------------------------}
Procedure Init;
Var i:Integer;
Begin
     TextBackGround(LightGray);
     ClrScr;
     TextColor(Blue);

     For i := 2 to 79 do
     Begin
          Gotoxy(i,1); Write(chr(205));
          Gotoxy(i,49); Write(chr(205));
          Gotoxy(i,8); Write(Chr(205));
     End;
     For i := 2 to 48 do
     Begin
          Gotoxy(1, i); Write(Chr(186));
          Gotoxy(80, i); Write(Chr(186));
     End;
     Gotoxy(1,1); Write(Chr(201));
     Gotoxy(80,1); Write(Chr(187));
     Gotoxy(1,8); Write(Chr(204));
     Gotoxy(80,8); Write(Chr(185));
     Gotoxy(1,49); Write(Chr(200));
     Gotoxy(80,49); Write(Chr(188));
     Gotoxy(20,8); Write(Chr(209));
     Gotoxy(20,49); Write(Chr(207));

     For i := 9 to 48 do
     Begin
          Gotoxy(20,i); Write(chr(179));
     End;

     Gotoxy(25,2);
     Write('SORTING ALGORITHMS DEMO PROGRAM');
     Gotoxy(8,4);
     TextColor(Red);
     Write('Faculty of Information Technology - Hanoi University of Technology');
     Gotoxy(30,6);
     TextColor(Blue);
     Write('Developer: Ha Minh Nam');

     Gotoxy(5, 10);
     Write('Algorithms:');

     For i := 2 to 19 do
     Begin
          Gotoxy(i, 12); Write(Chr(196));
     ENd;

     TextColor(Red);
     Gotoxy(3, 14); Write('1. SELECTION SORT');
     Gotoxy(3, 16); Write('2. INSERTION SORT');
     Gotoxy(3, 18); Write('3. BUBBLE SORT');
     Gotoxy(3, 20); Write('4. QUICK SORT');
     Gotoxy(3, 22); Write('5. MERGE SORT');
End;
{---------------------------End of Init------------------------------------}

{---------------------------Begin of OutPut--------------------------------}
Procedure OutPut(var max:Integer; blnMergeSort: boolean);
Var i, j:Integer;
Begin
     For i := 10 to 48 do
     Begin
          For j := 24 to 79 do
          Begin
               Gotoxy(j,i);
               Write(' ');
          End;
     End;

     Gotoxy(24, 10);
     Write('- Array before sorting: ');
     Gotoxy(24,12);
     TextColor(Red);
     For i := 1 to max do
     Begin
          Write(arrTmp[i], '  ');
     End;

     TextColor(Blue);
     Gotoxy(24, 15);
     Write('- Array after sorting: ');
     TextColor(Red);
     Gotoxy(24,17);

     If not blnMergeSort then


     For i := 1 to max do
     Begin
          Write(arrValue[i], '  ');
     End
     else
     For i := 1 to max do
     Begin
          Write(arrZ[i], '  ');
     End;
End;
{----------------------------------End of Output--------------------------}

{----------------------------------Begin of SELECTION_SORT----------------}
Procedure SELECTION_SORT(Var K:Array of Integer; numElement:Integer; direction:Integer);
Var i,j,m, X:Integer;
Begin
     If direction = 1 then
     Begin
          For i := 1 to numElement - 1 do
               Begin
                    m := i;
                    For j := i + 1 to numElement do
                        If K[j] < K[m] then m := j;
                        If (m <> i) Then
                        Begin
                             X := K[i];
                             K[i] := K[m];
                             K[m] := X;
                        End;
               End;
     End;

     If direction = 0 then
     Begin
          For i := 1 to numElement - 1 do
               Begin
                    m := i;
                    For j := i + 1 to numElement do
                        If K[j] > K[m] then m := j;
                        If (m <> i) Then
                        Begin
                             X := K[i];
                             K[i] := K[m];
                             K[m] := X;
                        End;
               End;
     End;

End;
{-----------------------------End of SELECTION_SORT------------------------}

{-----------------------------Begin of INSERTION_SORT----------------------}
Procedure INSERTION_SORT(Var K:Array of Integer; noe: Integer; dir:Integer);
Var i, j, X: Integer;
Begin

     K[0] := -32500;

     If dir = 1 then
     Begin
          For i := 2 to noe do
                    Begin
                         X := K[i];
                         j := i - 1;
                         While X < K[j] do
                         Begin
                              K[j+1] := K[j];
                              j := j - 1;
                         End;
                         K[j+1] := X;
                    End;
     End;

     If dir = 0 then  { This did not work, review later...}


     Begin
          For i := 2 to noe do
                    Begin
                         X := K[i];
                         j := i - 1;
                         While X > K[j] do
                         Begin
                              K[j+1] := K[j];
                              j := j - 1;
                         End;
                         K[j+1] := X;
                    End;
     End;

End;
{-------------------------End of INSERTION_SORT----------------------------}

{-------------------------Begin of BUBBLE_SORT-----------------------------}
Procedure BUBBLE_SORT(Var K:Array of Integer; numOfEle: Integer; dir:Integer);
Var i, j, X: Integer;
Begin
     If dir = 1 then
     For i := 1 to numOfEle do
         For j := numOfEle downto i + 1 do
             If K[j] < K[j-1] Then
                Begin
                     X := K[j];
                     K[j] := K[j-1];
                     K[j-1] := X;
                End;

     If dir = 0 then
     For i := 1 to numOfEle do
         For j := numOfEle downto i + 1 do
             If K[j] > K[j-1] Then
                Begin
                     X := K[j];
                     K[j] := K[j-1];
                     K[j-1] := X;
                End;
     Output(numOfEle, false);
End;
{------------------------End of BUBBLE_SORT--------------------------------}

{------------------------Begin of QUICK_SORT-------------------------------}
Procedure QUICK_SORT(Var K:Array of Integer; lowerBound: Integer; upperBound: Integer);
Var i, j, KEY, X, Y:Integer;
    B: boolean;
Begin
     B := true;
     If (lowerBound < upperBound) Then
     Begin
          i := lowerBound;

          j := upperBound + 1;

          KEY := K[lowerBound];

          While B Do
          Begin
               i := i + 1;
               While K[i] < KEY Do i := i + 1;
               j := j - 1;
               While K[j] > KEY Do j := j - 1;
               If i < j then
               Begin
                    X := K[i];
                    K[i] := K[j];
                    K[j] := X;
               End
               Else B := false;
          End;

          Y := K[lowerBound];
          K[lowerBound] := K[j];
          K[j] := Y;

          QUICK_SORT(K, lowerBound,j - 1);


          QUICK_SORT(K, j + 1, upperBound);
     End;

End;
{------------------------End of QUICK_SORT---------------------------------}

{------------------------Begin MERGE_SORT----------------------------------}
{ This is the two-way merge, is used for recursive call from straight two-way merge sort }
Procedure MERGE_SORT(Var X:Array of Integer; b: Integer; m: Integer; n: Integer; Var Z:Array
of Integer);
Var i, j, k, s: Integer;
Begin
     i := b;
     k := b;
     j := m + 1;

     While (i <= m) and (j <= n) Do


     Begin
           If X[i] <= X[j] Then
              Begin
                   Z[k] := X[i];
                   i := i + 1;
              End
              Else
              Begin
                   Z[k] := X[j];
                   j := j + 1;
              End;
              k := k + 1;
     End;

     If i > m then
     Begin
          For s := j to n do
          Begin
               Z[k] := X[s];
               k := k + 1;
          End;
     End
     Else
     Begin
          For s := i to m do
          Begin
               Z[k] := X[s];
               k := k + 1;
          End;
     End;

End;

{--------------------------End of MERGE_SORT-------------------------------}

{--------------------------Begin of MPASS----------------------------------}
Procedure MPASS(Var X:Array of Integer; Var Y:Array of Integer; n: Integer; l: Integer);
Var i, s:Integer;
Begin
     i := 1;

     While (i <= n - 2*l - 1) do


     Begin
          MERGE_SORT(X, i, i + l - 1, i + 2*l - 1, Y);
          i := i + 2*l;
     End;

     If (i + l - 1 < n) Then
     MERGE_SORT(X, i, i + l - 1, n, Y)
     Else
     Begin
          For s := i to n do
          Begin
               Y[s] := X[s];
          End;
     End;
End;
{--------------------------End of MPASS------------------------------------}

{--------------------------Begin of STRAIGHT_MERGE_SORT--------------------}
Procedure STRAIGHT_MERGE_SORT(Var X:Array of Integer; n:Integer);
Var l: Integer;
    Y: Array[0..99] of Integer;
Begin
     l := 1;

     While l < n do
     Begin
          MPASS(X, Y, n, l);
          l := l + 1;
          MPASS(Y, X, n, l);
          l := l + 1;
     End;
End;
{--------------------------End of STRAIGHT_MERGE_SORT----------------------}

{--------------------------Begin READ_FROM_FILE----------------------------}
Procedure READ_FROM_FILE;
Var Number, i:Integer;
Begin
     Assign(F, f_in);
     Reset(F);

     i := 1;

     While Not EOF(F) Do


     Begin
          Readln(F, Number);
          arrValue[i] := Number;
          i := i + 1;
     End;
     TotalElement := i-1;
     Close(F);
End;
{--------------------------End of READ_FROM_FILE---------------------------}

{--------------------------Begin WRITE_TO_FILE-----------------------------}
Procedure WRITE_TO_FILE(Alg:Integer);
Var i: Integer;
Begin
     Assign(F, f_out);
     Rewrite(F);
     Write(F, '-------- SORTING RESULT --------');
     Writeln(F);
     Write(F, '--- Algorithm used: ');
     Case Alg of
          1: Write(F, 'SELECTION SORT');
          2: Write(F, 'INSERTION SORT');
          3: Write(F, 'BUBBLE SORT');
          4: Write(F, 'QUICK SORT');
          5: Write(F, 'MERGE SORT');
     End;

     Writeln(F);

     For i := 1 to TotalElement Do
     Begin
          Writeln(F, i, '-', arrValue[i]);
     End;
     Close(F);
End;
{--------------------------End of WRITE_TO_FILE----------------------------}

{--------------------------Begin Input-------------------------------------}
Procedure Input;
Var n:char;
    num: Integer;
    i: Integer;
    a: Integer;
    o: Integer;
Begin
     Gotoxy(24, 10);
     TextColor(Blue);
     Write('- Import Values Manualy (N) or Automatically (A)?');
     Readln(n);
     If (n='N') or (n='n') then
     Begin
          Gotoxy(24, 12);
          Write('- Number of elements in array N='); Readln(num);
          For i := 1 to num do
          Begin
               Gotoxy(24, 12+2*i);
               Write('  + Element ', i, ' = ');
               Readln(arrValue[i]);
          End;

          For i := 1 to num do


          Begin
               arrTmp[i] := arrValue[i];
          End;

          Gotoxy(24, 14+2*num);


          Write('Sorting by ascending (1) or descending (0)?');
          Readln(o);
          Gotoxy(24, 16+2*num);
          Write('Select algorithm (1/2/3/4/5): ');
          Readln(a);
     End
     else if (n='A') or (n='a') then
     Begin
          Gotoxy(24, 12);
          Write('Select algorithm (1/2/3/4/5): ');
          Readln(a);

          READ_FROM_FILE;

          Case a of
               1: SELECTION_SORT(arrValue, TotalElement, 1);
               2: INSERTION_SORT(arrValue, TotalElement, 1);
               3: BUBBLE_SORT(arrValue, TotalElement, 1);
               4: QUICK_SORT(arrValue, 1, TotalElement);
               5: STRAIGHT_MERGE_SORT(arrValue, TotalElement);
          End;

          WRITE_TO_FILE(a);
          Gotoxy(24, 14);
          Write('Sorting completed. View file for result ');
     End;

     case a of
          1: Begin
                SELECTION_SORT(arrValue, num, o);
                Output(num, false);
             End;
          2: Begin
                  INSERTION_SORT(arrValue, num, o);
                  Output(num, false);
             End;
          3: Begin
                  BUBBLE_SORT(arrValue, num, o);
                  Output(num, false);
             End;
          4: Begin
                QUICK_SORT(arrValue, 1, num);
                Output(num, false);
             End;
          5: Begin
                  STRAIGHT_MERGE_SORT(arrValue, num);
                  OutPut(num, false);
             End;
     end;
End;
{-----------------------------End of Input---------------------------------}
{-----------------------------Main Program---------------------------------}
BEGIN
     Init;
     Input;
     Readln;
END.
{-----------------------------See you again !------------------------------}
{-------------------------I love computer and programming------------------}
Programming is the Art

$M 65520 0 655360}
program SortingAlgorithmsDemo;
uses crt;
const
  max = 15000;
  maxV = 15000;
  Interval = 1193180 / 65536;
  nMenu = 12;
  SMenu: array[0..nMenu] of String =
  (
    '  0. Display Input',
    '  1. Selection Sort',
    '  2. Bubble Sort',
    '  3. Insertion Sort',
    '  4. Insertion Sort with binary searching',
    '  5. Shell Sort',
    '  6. Quick Sort',
    '  7. Heap Sort',
    '  8. Distribution Counting',
    '  9. Radix Sort',
    ' 10. Straight Radix Sort',
    ' 11. Merge Sort',
    ' 12. Exit'
  );
type
  TArr = array[0..max + 1] of Integer;
var
  k: TArr;
  n: Integer;
  selected: Integer;
  StTime: LongInt;
  Time: LongInt absolute 0:$46C;

procedure Enter;
var
  f: Text;
begin
  Assign(f, 'SORT.INP'); Reset(f);
  n := 0;
  while not SeekEof(f) do
    begin
      Inc(n); Read(f, k[n]);
    end;
  Close(f);
  StTime := Time;
end;

procedure PrintInput;
var
  i: Integer;
begin
  Enter;
  for i := 1 to n do Write(k[i]:8);
  Write('Press any key to return to menu...');
  ReadKey
end;

procedure PrintResult;
var
  f: Text;
  i: Integer;
  ch: Char;
begin
  Writeln('During Time = ', (Time - StTime) / Interval:1:10, ' (s)');
  Assign(f, 'SORT.OUT'); Rewrite(f);
  for i := 1 to n do Writeln(f, k[i]);
  Close(f);
  Write('Press <P> to print Output, another key to return to menu...');
  ch := ReadKey; Writeln(ch);
  if Upcase(ch) = 'P' then
    begin
      for i := 1 to n do Write(k[i]:8);
      Writeln;
      Write('Press any key to return to menu...');
      ReadKey;
    end;
end;

procedure Swap(var x, y: Integer);       


var
  t: Integer;
begin
  t := x; x := y; y := t;
end;

(** SELECTION SORT *************************************************)


procedure SelectionSort;
var
  i, j, jmin: Integer;
begin
  Enter;
  for i := 1 to n - 1 do
    begin
      jmin := i;
      for j := i + 1 to n do
        if k[j] < k[jmin] then jmin := j;
      if jmin <> i then Swap(k[i], k[jmin]);
    end;
  PrintResult;
end;

(** BUBBLE SORT ****************************************************)


procedure BubbleSort;
var
  i, j: Integer;
begin
  Enter;
  for i := 2 to n do
    for j := n downto i do
      if k[j - 1] > k[j] then Swap(k[j - 1], k[j]);
  PrintResult;
end;

(** INSERTION SORT *************************************************)


procedure InsertionSort;
var
  i, j, tmp: Integer;
begin
  Enter;
  k[0] := 0;
  for i := 2 to n do
    begin
      tmp := k[i]; j := i - 1;
      while tmp < k[j] do
        begin
          k[j + 1] := k[j];
          Dec(j);
        end;
      k[j + 1] := tmp;
    end;
  PrintResult;
end;

(** INSERTION SORT WITH BINARY SEARCHING ***************************)


procedure AdvancedInsertionSort;
var
  i, inf, sup, median, tmp: Integer;
begin
  Enter;
  k[0] := 0;
  for i := 2 to n do
    if k[i] < k[i - 1] then
      begin
        tmp := k[i];
        inf := 0; sup := i - 1;
        repeat
          median := (inf + sup) shr 1;
          if k[median] > tmp then sup := median
          else inf := median;
        until inf + 1 >= sup;
        Move(k[sup], k[sup + 1], (i - sup) * SizeOf(k[1]));
        k[sup] := tmp;
      end;
  PrintResult;
end;
(** SHELL SORT *****************************************************)
procedure ShellSort;
var
  tmp: Integer;
  i, j, h: Integer;
begin
  Enter;
  h := n shr 1;
  while h <> 0 do
    begin
      for i := h + 1 to n do
        begin
          tmp := k[i]; j := i - h;
          while (j > 0) and (k[j] > tmp) do
            begin
              k[j + h] := k[j];
              j := j - h;
            end;
          k[j + h] := tmp;
        end;
      h := h shr 1;
    end;
  PrintResult;
end;

(** QUICK SORT *****************************************************)


procedure QuickSort;

  procedure Partition(L, H: Integer);


  var
    i, j: Integer;
    key: Integer;
  begin
    if L >= H then Exit;
    key := k[L + Random(H - L + 1)];
    i := L; j := H;
    repeat
      while k[i] < key do Inc(i);
      while k[j] > key do Dec(j);
      if i <= j then
        begin
          if i < j then Swap(k[i], k[j]);
          Inc(i); Dec(j);
        end;
    until i > j;
    Partition(L, j); Partition(i, H);
  end;

begin
  Enter;
  Partition(1, n);
  PrintResult;
end;

(** HEAP SORT ******************************************************)


procedure HeapSort;
var
  r, i: Integer;

  procedure Adjust(root, endnode: Integer);


  var
    key, c: Integer;
  begin
    key := k[root];
    while root shl 1 <= endnode do
      begin
        c := root shl 1;
        if (c < endnode) and (k[c] < k[c + 1]) then Inc(c);
        if k[c] <= key then Break;
        k[root] := k[c]; root := c;
      end;
    k[root] := key;
  end;

begin
  Enter;
  for r := n shr 1 downto 1 do Adjust(r, n);
  for i := n downto 2 do
    begin
      Swap(k[1], k[i]);
      Adjust(1, i - 1);
    end;
  PrintResult;
end;

(** DISTRIBUTION COUNTING ******************************************)


procedure DistributionCounting;
var
  c, x: TArr;
  i, V: Integer;
begin
  Enter;
  FillChar(c, SizeOf(c), 0);
  for i := 1 to n do Inc(c[k[i]]);
  for V := 1 to MaxV do c[V] := c[V - 1] + c[V];
  for i := n downto 1 do
    begin
      V := k[i];
      x[c[V]] := k[i];
      Dec(c[V]);
    end;
  k := x;
  PrintResult;
end;

(** EXCHANGE RADIX SORT ********************************************)


procedure RadixSort;
const
  MaxBit = 13;
var
  MaskBit: array[0..MaxBit] of Integer;
  MaxValue, i: Integer;

  procedure Partition(L, H, BIndex: Integer);


  var
    i, j, Mask: Integer;
  begin
    if L >= H then Exit;
    i := L; j := H; Mask := MaskBit[BIndex];
    repeat
      while (i < j) and (k[i] and Mask = 0) do Inc(i);
      while (i < j) and (k[j] and Mask <> 0) do Dec(j);
      Swap(k[i], k[j]);
    until i = j;
    if k[j] and Mask = 0 then Inc(j);
    if BIndex > 0 then
      begin
        Partition(L, j - 1, BIndex - 1); Partition(j, H, BIndex - 1);
      end;
  end;

begin
  Enter;
  for i := 0 to MaxBit do MaskBit[i] := 1 shl i;
  maxValue := k[1];
  for i := 2 to n do
    if k[i] > MaxValue then maxValue := k[i];
  i := 0;
  while (i < MaxBit) and (MaskBit[i + 1] <= MaxValue) do Inc(i);
  Partition(1, n, i);
  PrintResult;
end;

(** STRAIGHT RADIX SORT ********************************************)


procedure StraightRadixSort;
const
  Radix = 256;
  nDigit = 2;
var
  t: TArr;
  p: Integer;
  Flag: Boolean;

  function GetDigit(key, p: Integer): Integer;


  begin
    if p = 0 then GetDigit := key and $FF
    else GetDigit := key shr 8;
  end;

  procedure DCount(var x, y: TArr; p: Integer);


  var
    c: array[0..Radix - 1] of Integer;
    i, d: Integer;
  begin
    FillChar(c, SizeOf(c), 0);
    for i := 1 to n do
      begin
        d := GetDigit(x[i], p); Inc(c[d]);
      end;
    for d := 1 to Radix - 1 do c[d] := c[d - 1] + c[d];
    for i := n downto 1 do
      begin
        d := GetDigit(x[i], p);
        y[c[d]] := x[i];
        Dec(c[d]);
      end;
  end;

begin
  Enter;
  Flag := True;
  for p := 0 to nDigit - 1 do
    begin
      if Flag then DCount(k, t, p)
      else DCount(t, k, p);
      Flag := not Flag;
    end;
  if not Flag then k := t;
  PrintResult;
end;

(** MERGE SORT *****************************************************)


procedure MergeSort;
var
  t: TArr;
  Flag: Boolean;
  len: Integer;

  procedure Merge(var Source, Dest: TArr; a, b, c: Integer);


  var
    i, j, k: Integer;
  begin
    k := a; i := a; j := b + 1;
    while (i <= b) and (j <= c) do
      begin
        if Source[i] <= Source[j] then
          begin
            Dest[k] := Source[i]; Inc(i);
          end
        else
          begin
            Dest[k] := Source[j]; Inc(j);
          end;
        Inc(k);
      end;
    if i <= b then
      Move(Source[i], Dest[k], (b - i + 1) * SizeOf(Source[1]))
    else
      Move(Source[j], Dest[k], (c - j + 1) * SizeOf(Source[1]));
  end;

  procedure MergeByLength(var Source, Dest: TArr; len: Integer);


  var
    a, b, c: Integer;
  begin
    a := 1; b := len; c := len shl 1;
    while c <= n do
      begin
        Merge(Source, Dest, a, b, c);
        a := a + len shl 1; b := b + len shl 1; c := c + len shl 1;
      end;
    if b < n then Merge(Source, Dest, a, b, n);
  end;

begin
  Enter;
  len := 1; Flag := True;
  while len < n do
    begin
      if Flag then MergeByLength(k, t, len)
      else MergeByLength(t, k, len);
      len := len shl 1;
      Flag := not Flag;
    end;
  if not Flag then k := t;
  PrintResult;
end;
(*******************************************************************)

function MenuSelect: Integer;


var
  ch: Integer;
begin
  Clrscr;
  Writeln('Sorting Algorithms Demos; Input: SORT.INP; Output: SORT.OUT');
  for ch := 0 to nMenu do Writeln(SMenu[ch]);
  Write('Enter your choice: '); Readln(ch);
  MenuSelect := ch;
end;

begin
  repeat
    selected := MenuSelect;
    Writeln(SMenu[selected]);
    case selected of
      0: PrintInput;
      1: SelectionSort;
      2: BubbleSort;
      3: InsertionSort;
      4: AdvancedInsertionSort;
      5: ShellSort;
      6: QuickSort;
      7: HeapSort;
      8: DistributionCounting;
      9: RadixSort;
      10: StraightRadixSort;
      11: MergeSort;
      12: Halt;
    end;
  until False;
end.

Вам также может понравиться