Nichtrekursive Implementation von Quicksort: | ||
procedure quicksort; | ||
var t,i,l,r: integer; | ||
begin | ||
l:=1; r:=N; stackinit; | ||
pusch (l); pusch (r); | ||
repeat | ||
if r >l then | ||
begin | ||
i:=partition(l,r); | ||
if (i-l)>(r-i) | ||
then begin push(l);push (i-1);l:= i+1 end | ||
else begin push (i+1); push (r); r:=i-1 end; | ||
end | ||
else | ||
begin r:=pop; l:=pop end; | ||
until stackempty; | ||
end; |
Dieses Programm unterscheidet sich in zwei wesentlichen Hinsichten. Zum einen werden die zwei Teildateien nicht in irgendeiner willkürlichen Reihenfolge im Stapel abgelegt, sondern ihre Größen werden geprüft, und die größere von beiden wird zuerst im Stapel abgelegt. Zum anderen wird die kleinere der beiden Teildateien überhaupt nicht im Stapel abgelegt; die Werte der Parameter werden einfach geändert. Für Quicksort führt die Bearbeitung der kleineren von den beiden Teildateien zunächst dazu, daß der Stapel für nur ungefähr lgN Eintragungen Platz haben muß, da es sich bei jeder weiteren Ablage nach der ersten im Stapel um eine Teildatei handeln muß, die weniger als halb so groß ist wie die zuvor abgelegte. Die einfache Verwendung eines expliziten Stapels führt zu einem weit effizienten Programm als die direkte rekursive Implementation. Es gibt doch noch Ballast. Das Problem besteht darin, daß wenn beide Teildateien nur ein Element besitzen, eine Datei mit r=l im Stapel abgelegt wird, nur um sofort entnommen und entfernt zu werden. Diese Änderung ist sehr einfach. Sie bewirkt, daß auch kleine Teildateien ignoriert werden. Für jede Datei verarbeitet die nichtrekursive Methode die gleichen Teildateien wie die rekursive Methode, allerdings in anderer Reihenfolge. |
|
Zurück |