1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
interface
TSorter = class
private
FDataStart: Pointer;
FDataSize: Integer;
protected
function GetDataSize: Integer; virtual; abstract;
property Length: Integer read FLength;
procedure Swap(I1, I2: Integer); virtual; abstract;
function Compare(I1, I2: Integer); virtual; abstract;
procedure Sort(L, R: Integer);
function GetData(Index: Integer): Pointer;
property Data[Index: Integer]: Pointer read GetData;
public
procedure Execute(DataStart: Pointer; Length: Integer);
End;
PPersonne = ^TPersonne;
TPersonne = record
Nom: string;
Prenom: string;
end;
TPersonneSorter = class(TSorter)
protected
function GetPersonne: TPersonne;
procedure SetPersonne(Index: Integer; Value: TPersonne);
function GetDataSize: Integer; override;
procedure Swap(I1, I2: Integer); override;
function Compare(I1, I2: Integer); override;
function Personne[Index : Integer]: TPersonne read GetPersonne write SetPersonne;
End;
implementation
function TSorter.GetData(Index: Integer): Pointer;
begin
// Retourne l'élément de rang Index
Result := FDataStart + Index * FDataSize;
End;
// QuickSort
procedure TSorter.Sort(L, R: Integer);
var
I, J: Integer;
M: Pointer;
begin
repeat
I := L;
J := R;
M := Data[(L + R) shr 1];
repeat
while (Compare(Data[I], M)) < 0 do
Inc(I);
while (Compare(Data[J], M)) > 0 do
Dec(J);
if I <= J then
begin
Swap(Data[I], Data[J]);
Inc(I);
Dec(J);
end;
until I > J;
if L < J then
Sort(L, J);
L := I;
until I >= R;
End;
procedure TSorter.Execute(DataStart: Pointer; Length: Integer);
begin
FDataStart := DataStart;
FDataSize := GetDataSize; // Initialise la taille des éléments à trier
Sort(0, Length);
End;
{ TPersonneSorter }
function TPersonneSorter.GetPersonne(Index : Integer): TPersonne;
begin
Result := TPersonne(Data[Index])^;
End;
procedure TPersonneSorter.SetPersonne(Index: Integer; Value: TPersonne);
begin
with TPersonne(Data[Index])^ do
begin
Nom := Value.Nom;
Prenom := Value.Prenom;
end;
End;
function TPersonneSorter.GetDataSize: Integer;
begin
Result := SizeOf(TPersonne);
End;
function TPersonneSorter.Compare(I1, I2: Integer);
begin
// Compare d'abord les noms
Result := CompareText(Personne[I1].Nom, Personne[I2].Nom);
if Result = 0 then
// en cas d'égalité, compare les prénoms
Result := CompareText(Personne[I1].Prenom, Personne[I2].Prenom);
End;
procedure TPersonneSorter.Swap(I1, I2: Integer);
var
P: Personne;
begin
P := Personne[I1];
Personne[I1] := Personne[I2];
Personne[I2] := P;
End;
// exemple d'utilisation
var
T : array[0..10] of TPersonne;
PS: TPersonneSorter;
begin
// Remplissage du tableau
// ...
// Tri
PS := TPersonneSorter.Create;
try
PS.Execute(@T[0], Length(T));
finally
FreeAndNil(PS);
end; |
Partager