mysticbbs/mdl/m_quicksort.pas

142 lines
2.8 KiB
ObjectPascal
Raw Normal View History

2012-02-13 15:54:14 -08:00
{$I M_OPS.PAS}
Unit m_QuickSort;
Interface
Const
2012-03-03 19:08:07 -08:00
mdlMaxSortSize = 10000;
2012-02-13 15:54:14 -08:00
Type
TSortMethod = (qAscending, qDescending);
PQuickSortRec = ^TQuickSortRec;
TQuickSortRec = Record
Name : String;
Ptr : LongInt;
End;
TQuickSort = Class
Total : Word;
Data : Array[1..mdlMaxSortSize] of PQuickSortRec;
Constructor Create;
Destructor Destroy; Override;
2012-03-03 19:08:07 -08:00
Function Add (Name: String; Ptr: Cardinal) : Boolean;
2012-03-10 15:07:47 -08:00
Procedure Conditional (Name: String; Ptr: Cardinal; ListMin: Word; Mode: TSortMethod);
2012-03-03 19:08:07 -08:00
Procedure Sort (Left, Right: Word; Mode: TSortMethod);
2012-02-13 15:54:14 -08:00
Procedure Clear;
End;
Implementation
Constructor TQuickSort.Create;
Begin
Inherited Create;
Total := 0;
End;
Destructor TQuickSort.Destroy;
Begin
Clear;
Inherited Destroy;
End;
Procedure TQuickSort.Clear;
Var
Count : Word;
Begin
For Count := 1 to Total Do
Dispose (Data[Count]);
Total := 0;
End;
2012-03-03 19:08:07 -08:00
Function TQuickSort.Add (Name: String; Ptr: Cardinal) : Boolean;
2012-02-13 15:54:14 -08:00
Begin
Result := False;
Inc (Total);
New (Data[Total]);
If Data[Total] = NIL Then Begin
Dec (Total);
Exit;
End;
Data[Total]^.Name := Name;
Data[Total]^.Ptr := Ptr;
Result := True;
End;
2012-03-10 15:07:47 -08:00
Procedure TQuickSort.Conditional (Name: String; Ptr: Cardinal; ListMin: Word; Mode: TSortMethod);
2012-03-03 19:08:07 -08:00
Var
Count : Word;
2012-03-10 15:07:47 -08:00
Ok : Boolean;
2012-03-03 19:08:07 -08:00
Begin
If Total < ListMin Then
Self.Add(Name, Ptr)
Else
2012-03-10 15:07:47 -08:00
For Count := Total DownTo 1 Do Begin
Case Mode of
qDescending : Ok := Data[Count]^.Name < Name;
qAscending : Ok := Data[Count]^.Name > Name;
End;
If Ok Then Begin
2012-03-04 13:58:57 -08:00
Data[Count]^.Name := Name;
Data[Count]^.Ptr := Ptr;
Break;
2012-03-03 19:08:07 -08:00
End;
2012-03-10 15:07:47 -08:00
End;
2012-03-03 19:08:07 -08:00
End;
2012-02-13 15:54:14 -08:00
Procedure TQuickSort.Sort (Left, Right: Word; Mode: TSortMethod);
Var
Temp : PQuickSortRec;
Pivot : TQuickSortRec;
Lower : Word;
Upper : Word;
Middle : Word;
Begin
If Total = 0 Then Exit;
Lower := Left;
Upper := Right;
Middle := (Left + Right) DIV 2;
Pivot := Data[Middle]^;
Repeat
Case Mode of
qAscending : Begin
While Data[Lower]^.Name < Pivot.Name Do Inc(Lower);
While Pivot.Name < Data[Upper]^.Name Do Dec(Upper);
End;
qDescending : Begin
While Data[Lower]^.Name > Pivot.Name Do Inc(Lower);
While Pivot.Name > Data[Upper]^.Name Do Dec(Upper);
End;
End;
If Lower <= Upper Then Begin
Temp := Data[Lower];
Data[Lower] := Data[Upper];
Data[Upper] := Temp;
Inc (Lower);
Dec (Upper);
End;
Until Lower > Upper;
If Left < Upper Then Sort(Left, Upper, Mode);
If Lower < Right Then Sort(Lower, Right, Mode);
End;
End.