Autor Beitrag
TheAxeEffect
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 37



BeitragVerfasst: So 12.08.07 15:05 
hi liebe community,
ich habe ein kleines verständisproblem bei einem(also besser gesagt allen)Code für den quicksort algorithmus.(Fragen stehen bei den betreffenden stellen im sourcecode)
ausblenden volle Höhe Delphi-Quelltext
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:
unit URandomQuickSort;

interface

procedure RandomQuickSort(var A: array of Integer);

implementation

procedure RandomQuickSort(var A: array of Integer);

  procedure RQSort(LoIndex, HiIndex: Integer);
  var
    Lo, Hi: Integer;
    Pivot: Integer;
    Swap: Integer;
  begin

    { Zufallsstrategie:
      Sei das Pivot-Element stets ein zufällig
      gewähltes Element der Liste }


    Pivot := A[LoIndex + Random(HiIndex - LoIndex)];//nr1. woher wieß das programm, dass sich highindex auf die länge des arrays "A" bezieht? ist doch nirgendwo deklariert oder? also sowas wie highindex:=higth(A) oder so

    { Der Rest wie gehabt! }

    Lo := LoIndex;   //ok, das versteh ich: am anfang ist Lo der kleinste wert im array, und Hi der höchste.
    Hi := HiIndex;
    repeat
      while A[Lo] < Pivot do Inc(Lo); // auch klar. solange er nix gefunden hat, sucht er halt weiter.
      while A[Hi] > Pivot do Dec(Hi);
      if Lo <= Hi then 
      begin
        Swap := A[Lo];
        A[Lo] := A[Hi]; //wenn ich das richtig verstanden habe, funktioniert das so: wenn diese beiden variablen sich getroffen haben, tauschen die sozusagen platz, dh jetzt is hi unten und lo oben...
        A[Hi] := Swap;
        Inc(Lo);
        Dec(Hi);
      end;
    until Lo > Hi;  //Das heißt, dass er solange diese while schleife macht, bis er was gefunden hat nehm ich mal an.
    if LoIndex < Hi then RQSort(LoIndex, Hi);  //ok, da hab  ich kein plan was gemeint  is. wär nett wenn man mir das erklären könnte :-)
    if Lo < HiIndex then RQSort(Lo, HiIndex);
  end;

begin
  RQSort(Low(A), High(A)); //auch kein plan.
end;

initialization
  Randomize;

end.


danke im vorraus für die erklärungsarbeit^^
mfg,
simon
ps: achja, noch zwei fragen:
er wechselt das pivot-element soweit ich erkennen kann nie, was mich etwas stutzig macht...
und nocheine: so wie ich mir den quicksort vorstelle geht das so: es gibt ne liste, davon wird wie auch immer, ein verglichelement(pivot-element) ausgewählt...alle zahlen in der liste, die kleiner sind als das pivoteleent, kommen in eine liste, die anderen zahlen in die andere...das pivotelement kommt in irgendeine...danach macht manb das bei den zwei twillisten wieder und wieder und wieder, bis die listen so klein sind, dass sie nur noch eine bzw. zwei zahlen enthalten...danach wird alles wieder zusammengefügt...es entsteht also sowas wie nen binärer baum...dieses schema ist für mich hier überhaupt nicht erstichtlich, was zusätzlich zu meienr verwirrung beiträgt^^
dummzeuch
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 593
Erhaltene Danke: 5


Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
BeitragVerfasst: So 12.08.07 15:31 
user profile iconTheAxeEffect hat folgendes geschrieben:

Pivot := A[LoIndex + Random(HiIndex - LoIndex)];
//nr1. woher wieß das programm, dass sich highindex auf die länge des arrays "A" bezieht? ist doch nirgendwo deklariert oder? also sowas wie highindex:=higth(A) oder so


HiIndex und LoIndex mussen als Parameter an die Funktion uebergeben werden. Es wird nur der Bereich zwischen LoIndex und HiIndex sortiert.

Zitat:

Lo := LoIndex; //ok, das versteh ich: am anfang ist Lo der kleinste wert im array, und Hi der höchste.

Nein, am Anfang ist Lo der erste und Hi der letzte Wert im Array.

Zitat:

A[Lo] := A[Hi]; //wenn ich das richtig verstanden habe, funktioniert das so: wenn diese beiden variablen sich getroffen haben, tauschen die sozusagen platz, dh jetzt is hi unten und lo oben...

Ja. Der Algorithmus hat im unteren Bereich ein Element gefunden, das groesser ist als das Pivot-Element und im oberen eines, das kleiner ist. Diese beiden werden nun vertauscht.

Zitat:

until Lo > Hi; //Das heißt, dass er solange diese while schleife macht, bis er was gefunden hat nehm ich mal an.

Er macht solange weiter, bis sich der untere und der obere Index treffen. Wenn das der Fall ist, ist alles unterhalb davon kleiner als das Pivot Element, alles oberhalb ist groesser.

Zitat:

if LoIndex < Hi then RQSort(LoIndex, Hi); //ok, da hab ich kein plan was gemeint is. wär nett wenn man mir das erklären könnte :-)
if Lo < HiIndex then RQSort(Lo, HiIndex);

Ganz einfach: Nachdem das Array jetzt vorsortiert wurde, wird fuer die beiden Teile des Arrays wieder Quicksort aufgerufen.

Zitat:

begin
RQSort(Low(A), High(A)); //auch kein plan.
end;


Das ist der 1. Aufruf des Algorithmus. Hier werden die beiden Grenzen, ueber die Du Dich oben gewundert hast, uebergeben.

Zitat:

er wechselt das pivot-element soweit ich erkennen kann nie, was mich etwas stutzig macht...

Innerhalb eines Aufrufs wechselt man es auch nicht, aber es gibt ja fuer jede Haelfte einen neuen Aufruf, in dem das Pivot-Element neu bestimmt wird.

Zitat:

und nocheine: so wie ich mir den quicksort vorstelle geht das so: es gibt ne liste, davon wird wie auch immer, ein verglichelement(pivot-element) ausgewählt...alle zahlen in der liste, die kleiner sind als das pivoteleent, kommen in eine liste, die anderen zahlen in die andere...das pivotelement kommt in irgendeine...danach macht manb das bei den zwei Teillisten wieder und wieder und wieder, bis die listen so klein sind, dass sie nur noch eine bzw. zwei zahlen enthalten...danach wird alles wieder zusammengefügt...es entsteht also sowas wie nen binärer baum...dieses schema ist für mich hier überhaupt nicht erstichtlich, was zusätzlich zu meienr verwirrung beiträgt^^

Es wird danach nichts zusammengefuegt sondern jeder rekursive Aufruf arbeitet auf dem gleichen Array, nur eben auf einem Teil davon, der durch die untere und obere Grenze vorgegeben wird.

twm
TheAxeEffect Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 37



BeitragVerfasst: So 12.08.07 15:43 
Zitat:

A[Lo] := A[Hi]; //wenn ich das richtig verstanden habe, funktioniert das so: wenn diese beiden variablen sich getroffen haben, tauschen die sozusagen platz, dh jetzt is hi unten und lo oben...

Ja. Der Algorithmus hat im unteren Bereich ein Element gefunden, das groesser ist als das Pivot-Element und im oberen eines, das kleiner ist. Diese beiden werden nun vertauscht.

das versteh ich nicht!
warum hat der algo dann, sowas gefunden? woran erkenn ich das?
nur weil LO<=hi heißt noch nix oder?
was bedeutet in diesem fall lo<hi überhaupt?
TheAxeEffect Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 37



BeitragVerfasst: So 12.08.07 15:58 
ok, jetzt hab ichs verstandne. er ruft ja erst die "if" funktion auf, wenn er mit dem increasen von lo und decreasen von hi fertig ist....kk, klar, dass er dann was gefunden hat.
ich versteh aber noch immer nicht, wie er auf die werte für loindex und hiindex kommt, und ob sich die ändern und so..
dummzeuch
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 593
Erhaltene Danke: 5


Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
BeitragVerfasst: So 12.08.07 16:10 
user profile iconTheAxeEffect hat folgendes geschrieben:
ok, jetzt hab ichs verstandne. er ruft ja erst die "if" funktion auf, wenn er mit dem increasen von lo und decreasen von hi fertig ist....kk, klar, dass er dann was gefunden hat.
ich versteh aber noch immer nicht, wie er auf die werte für loindex und hiindex kommt, und ob sich die ändern und so..


Die werden als Parameter uebergeben, und zwar beim ersten Aufruf als Low(a) und High(a):

ausblenden Quelltext
1:
RQSort(Low(A), High(A));					


und bei den rekursiven Aufrufen jeweils als LoIndex und Hi bzw. Lo und HiIndex.
ausblenden Quelltext
1:
2:
if LoIndex < Hi then RQSort(LoIndex, Hi);
if Lo < HiIndex then RQSort(Lo, HiIndex);


twm
TheAxeEffect Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 37



BeitragVerfasst: So 12.08.07 16:23 
aber so wie ich das verstanden habe, ändern sich ja loindex und hiindex nicht, da ja loindex low(A) und hiindex high(A) ist, und diese werte sich ja nicht ändern...aber das kann ja nicht sein^^ würdest du mir noch erklären wo sich lo und hiindex ändern?^^
edit: vergisses, hab mich verlesen...is alles klar.(bis jetzt)
VIELEN Dank für deine hilfe.
mfg,
simon