Hallo.
Habt ihr euch nicht auch schon geärgert, dass man für jeden neuen dynamischen Array-Typ ne eigene Sortierprozedur schreiben muss oder dass ihr einen bestimmten strukturierten Array-Typ (array of record) nach verschiedenen Kriterien sortieren wollt und dabei die Sortierprozedur unübersichtlich wird?
Ich denke, dass ich hier eine Lösung hab. Sie basiert auf Pointern und sieht daher vll etwas umständlich aus, sollte allerdings sehr allgemein und daher flexibel sein.
Delphi-Quellcode:
unit Sort;
interface
type TCmpFkt =
function(P : Pointer; a, b : integer) : boolean;
//TExchFkt = procedure(P : Pointer; a, b : integer);
procedure ShSortArr(P : Pointer; Size, ElSize : integer; CmpFkt : TCmpFkt);
implementation
procedure Exch(P : Pointer; ElSize : integer; a, b : integer);
var P1, P2 : Pointer;
B1 : byte;
x : integer;
begin
P1 := Pointer(Integer(P) + ElSize * a);
P2 := Pointer(Integer(P) + ElSize * b);
for x := 0
to ElSize-1
do
begin
b1 := Byte(Pointer(Integer(P1)+x)^);
Byte(Pointer(Integer(P1)+x)^) := Byte(Pointer(Integer(P2)+x)^);
Byte(Pointer(Integer(P2)+x)^) := b1;
end;
end;
procedure ShSortArr(P : Pointer; Size, ElSize : integer; CmpFkt : TCmpFkt);
var k, i, j, bis: integer;
begin
bis := Size - 1;
if Size = 2
then
begin
if CmpFkt(P, 0, 1)
then
Exch(P, ElSize, 0, 1);
end;
k := bis
shr 1;
while k > 0
do
begin
for i := 0
to bis-k
do
begin
j := i;
while (j >= 0)
and
(CmpFkt(P, j, j+k))
do
begin
Exch(P, ElSize, j, j+k);
If j > k
then
Dec(j,k)
else if j = 0
then
break
else
j := 0;
end;
end;
k := k
shr 1;
end;
end;
end.
Ne Verlgeichsprozedur, um 2 Elemente zu vergleichen, kann z.B. so aussehen:
Delphi-Quellcode:
type tintarr = array of integer;
function Cmp(P : Pointer; a, b : integer) : boolean;
begin
result := tintarr(P)[b] < tintarr(P)[a];
end;
So habt ihr die Möglichkeit, die Sortierrichtung zu bestimmen und bei records das Vergleichskriterium.
Beispiel für records:
Delphi-Quellcode:
type trecarr = array of record
name : string;
plz : integer;
end;
function Cmp(P : Pointer; a, b : integer) : boolean;
begin
result := trecarr(P)[b].plz < trecarr(P)[a].plz;
end;
Der Sortieraufruf sieht dann so aus:
ShSortArr(Arr, Length(Arr), SizeOf(Arr[0]), Cmp);
Dabei ist Arr das Array, Cmp die Vergleichsprozedur.
Für Feedback und Verbesserungsvorschläge bin ich offen.
Gruß
Michael
[Edit]Natürlich kann man hier auch noch ne Standard-Vergleichsprozedur einbauen (ähnlich aufgebaut wie die Exch-Prozedur), die dann bei Bedarf durch eine eigene ersetzt wird.[/Edit]