![]() |
ShellSort für beliebige Arrays
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:
Ne Verlgeichsprozedur, um 2 Elemente zu vergleichen, kann z.B. so aussehen:
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.
Delphi-Quellcode:
So habt ihr die Möglichkeit, die Sortierrichtung zu bestimmen und bei records das Vergleichskriterium.
type tintarr = array of integer;
function Cmp(P : Pointer; a, b : integer) : boolean; begin result := tintarr(P)[b] < tintarr(P)[a]; end; Beispiel für records:
Delphi-Quellcode:
Der Sortieraufruf sieht dann so aus:
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;
Delphi-Quellcode:
Dabei ist Arr das Array, Cmp die Vergleichsprozedur.
ShSortArr(Arr, Length(Arr), SizeOf(Arr[0]), Cmp);
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] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz