![]() |
Quicksort
Hi,
ich muss ein Array mit Quicksort sortieren. Hier der Quellcode der Procedure:
Delphi-Quellcode:
ich rufe diese procedure so auf:
var
QS_liste: Array[1..10] of integer; l_pos, r_pos, pivot, temp, pivot_feld : integer; {...} procedure Quicksort(var a: array of integer; anfang, ende:integer); var i: integer; begin pivot_feld := (anfang+ende)div 2; pivot := a[pivot_feld]; l_pos := anfang; r_pos := ende; repeat while a[l_pos] < pivot do inc(l_pos); while a[r_pos] > pivot do dec(r_pos); if l_pos < r_pos then begin temp := a[l_pos]; a[l_pos] := a[r_pos]; a[r_pos] := temp; inc(l_pos); dec(r_pos); end; until (l_pos > r_pos) ; if (anfang < r_pos) then quicksort(a, anfang, r_pos); if (l_pos < ende) then quicksort(a, l_pos, ende); end;
Delphi-Quellcode:
DAs problem ist, dass er komischerweise immer ein Feld verändert.
QuickSort(QS_liste, 1, 10);
z.b.: in qs_liste vor beginn der procdure: 2, 54, 48, 1, 85, 2, 58, 77, 92, 31 nach dem das programm gelaufen ist wurde z.b. die zahl 48 durch die zahl 7 ersetzt. Wäre für eure hilfe sehr dankbar. mfg bonanza |
Re: Quicksort
Hallo bonanza,
der Fehler in deinem Programm tritt wegen einer Indexverschiebung auf. Das Array QS_Liste, welches du beim Aufruf übergibst, ist 1-basiert (Index 1..10). Der Parameter a der Routine Quicksort ist aber ein "open array" und damit 0-basiert. Die einfachste Lösung besteht darin, das Feld QS_Liste auch auf eine 0-basierte Adressierung umzustellen. Gruß Hawkeye |
Re: Quicksort
hallo bonanza,
1) Die Variablen l_pos, r_pos, pivot, temp, pivot_feld müssen lokal, d.h. innerhalb der Prozedur Quicksort definiert sein. 2) Wenn Du das Array als Parameter übergibst, dann solltest Du es als array[0..9] definieren. edit: 3) bei " if l_pos < r_pos then begin " muß es heißen "<=". |
Re: Quicksort
dakne für die antworten.
funktioniert jetzt auch soweit. Zitat:
ich habe jetzt all diese Arrayteile in Editfelder ausgegeben um den vorgang des Quicksort zu visualisieren. so mache ich immer einen Pfeil unter dem Editfeld, wo gerade das "Pivot-feld" ist und die Felder, die getauscht werden sollen. dann: rote markierung sleep(1000); tausch aktualisierung der Editfelder grüne markierung; sleep(1000); demarkierung der felder (mit weiß) Doch aus irgendeinem Grund hängt sich dsa Programm immer auf, sobald ich die sleep funktionen reinmache also nicht, dass es dann nur für die 1 sek stehen bleibt sondern, dann werden noch ncihtmal die felder markiert und es hängt sich eben auf. der Quellcode dazu:
Delphi-Quellcode:
{...}
procedure aktualisieren; var j: integer; begin for j := 0 to 9 do begin case j of 0: form1.edit1.text := inttostr(ss_liste[j]); 1: form1.edit2.text := inttostr(ss_liste[j]); 2: form1.edit3.text := inttostr(ss_liste[j]); 3: form1.edit4.text := inttostr(ss_liste[j]); 4: form1.edit5.text := inttostr(ss_liste[j]); 5: form1.edit6.text := inttostr(ss_liste[j]); 6: form1.edit7.text := inttostr(ss_liste[j]); 7: form1.edit8.text := inttostr(ss_liste[j]); 8: form1.edit9.text := inttostr(ss_liste[j]); 9: form1.edit10.text := inttostr(ss_liste[j]); end; // von CASE end; // von FOR end; procedure markiere (farbe:tcolor;x:integer); begin case x of 0: form1.edit1.color := farbe; 1: form1.edit2.color := farbe; 2: form1.edit3.color := farbe; 3: form1.edit4.color := farbe; 4: form1.edit5.color := farbe; 5: form1.edit6.color := farbe; 6: form1.edit7.color := farbe; 7: form1.edit8.color := farbe; 8: form1.edit9.color :=farbe; 9: form1.edit10.color := farbe; end; // von CASE end; procedure demarkiere(v:integer); begin case v of 0: form1.edit1.color := clWindow; 1: form1.edit2.color := clWindow; 2: form1.edit3.color := clWindow; 3: form1.edit4.color := clWindow; 4: form1.edit5.color := clWindow; 5: form1.edit6.color := clWindow; 6: form1.edit7.color := clWindow; 7: form1.edit8.color := clWindow; 8: form1.edit9.color := clWindow; 9: form1.edit10.color := clWindow; end; // von CASE end; procedure markieren_pivot (z:integer); begin case z of 0: form1.image1.visible := true; 1: form1.image2.visible := true; 2: form1.image3.visible := true; 3: form1.image4.visible := true; 4: form1.image5.visible := true; 5: form1.image6.visible := true; 6: form1.image7.visible := true; 7: form1.image8.visible := true; 8: form1.image9.visible := true; 9: form1.image10.visible := true; end; // von CASE end; procedure demarkiere_pivot (z:integer); begin case z of 0: form1.image1.visible := false; 1: form1.image2.visible := false; 2: form1.image3.visible := false; 3: form1.image4.visible := false; 4: form1.image5.visible := false; 5: form1.image6.visible := false; 6: form1.image7.visible := false; 7: form1.image8.visible := false; 8: form1.image9.visible := false; 9: form1.image10.visible := false; end; // von CASE end; procedure Quicksort(var a: array of integer; anfang, ende:integer); var i, l_pos, r_pos, pivot, temp, pivot_feld: integer; begin pivot_feld := (anfang+ende)div 2; demarkiere_pivot(pivot_feld); pivot := a[pivot_feld]; markieren_pivot(pivot_feld); l_pos := anfang; r_pos := ende; repeat while a[l_pos] < pivot do inc(l_pos); while a[r_pos] > pivot do dec(r_pos); if l_pos < r_pos then begin markiere(clRed, l_pos); markiere(clRed, r_pos); sleep(1000); temp := a[l_pos]; a[l_pos] := a[r_pos]; a[r_pos] := temp; aktualisieren; markiere(clGreen, l_pos); markiere(clGreen, r_pos); sleep(500); for i := 0 to 9 do demarkiere(i); inc(l_pos); dec(r_pos); end; until (l_pos > r_pos) ; if (anfang < r_pos) then quicksort(a, anfang, r_pos); if (l_pos < ende) then quicksort(a, l_pos, ende); end; |
Re: Quicksort
zu deinem Code ... ich denke ein FindComponent könnte diese CASE-Konstrukte wesentlich leserlicher ersetzen :)
|
Re: Quicksort
Zitat:
könntest du mir ein beispiel geben ? danke schonmal im voraus |
Re: Quicksort
beispiel ... aber immer doch :mrgreen:
![]() so wird z.B. aus
Delphi-Quellcode:
dieses
case j of
0: form1.edit1.text := inttostr(ss_liste[j]); 1: form1.edit2.text := inttostr(ss_liste[j]); 2: form1.edit3.text := inttostr(ss_liste[j]); 3: form1.edit4.text := inttostr(ss_liste[j]); 4: form1.edit5.text := inttostr(ss_liste[j]); 5: form1.edit6.text := inttostr(ss_liste[j]); 6: form1.edit7.text := inttostr(ss_liste[j]); 7: form1.edit8.text := inttostr(ss_liste[j]); 8: form1.edit9.text := inttostr(ss_liste[j]); 9: form1.edit10.text := inttostr(ss_liste[j]); end; // von CASE
Delphi-Quellcode:
'Edit' + IntToStr(j) bildet sozusagen den Namen der Componente, die man sucht
TEdit(Form1.FindComponent('Edit' + IntToStr(j))).Text := IntToStr(ss_liste[j]);
|
Re: Quicksort
super danke
das nenne ich ne verkürzung ^^ hat denn noch jemand ne idee warum das programm stockt ?
Delphi-Quellcode:
aufruf mit:
procedure aktualisieren;
var j: integer; begin for j := 1 to 10 do TEdit(Form1.FindComponent('Edit' + IntToStr(j))).Text := IntToStr(ss_liste[j]); end; procedure markiere (farbe:tcolor;x:integer); begin TEdit(Form1.FindComponent('Edit' + IntToStr(x))).color := farbe; end; procedure demarkiere(v:integer); begin TEdit(Form1.FindComponent('Edit' + IntToStr(v))).color := clWindow; end; procedure markieren_pivot (z:integer); begin TEdit(Form1.FindComponent('image' + IntToStr(z))).visible := true; end; procedure demarkiere_pivot (z:integer); begin TEdit(Form1.FindComponent('image' + IntToStr(z))).visible := false; end; procedure Quicksort(var a: array of integer; anfang, ende:integer); var i, l_pos, r_pos, pivot, temp, pivot_feld: integer; begin pivot_feld := (anfang+ende)div 2; for i := 1 to 10 do demarkiere_pivot(i); pivot := a[pivot_feld]; markieren_pivot(pivot_feld); l_pos := anfang; r_pos := ende; repeat while a[l_pos] < pivot do inc(l_pos); while a[r_pos] > pivot do dec(r_pos); if l_pos < r_pos then begin markiere(clRed, l_pos); markiere(clRed, r_pos); sleep(1000); temp := a[l_pos]; a[l_pos] := a[r_pos]; a[r_pos] := temp; aktualisieren; markiere(clGreen, l_pos); markiere(clGreen, r_pos); sleep(1000); for i := 1 to 10 do demarkiere(i); inc(l_pos); dec(r_pos); end; until (l_pos > r_pos) ; if (anfang < r_pos) then quicksort(a, anfang, r_pos); if (l_pos < ende) then quicksort(a, l_pos, ende); end;
Delphi-Quellcode:
QuickSort(ss_liste, 0, 9);
|
Re: Quicksort
Das mit dem Aufhängen ...
Das Sleep macht ja 'ne Pause bei jedem Schritt, also alles OK. Nur braucht jetzt die gesamte Prozedur solange, wie alle Sleeps, die aufgerufen brauchen ... wenn also Slepp(1000) 1000-mal aufgerufen wird, dann ergibt das 1000 Sekunden. Du änderst zwar die Eigenschaften, aber aktualisierst nicht die Oberfläche, noch gibts du der Form etwas Zeit sich mal um ihre angelegenheiten zu kümmern ... mach mal vor die Sleep's noch ein Application.ProcessMessages; |
Re: Quicksort
danke das läuft jetzt schonmal flüssig
aber ich habe manchmal einen Error in der markierten zeile
Delphi-Quellcode:
der Error is eine EAccessVioliation
{...}
markiere(clRed, l_pos); markiere(clRed, r_pos); Application.ProcessMessages; sleep(1000); temp := a[l_pos]; a[l_pos] := a[r_pos]; a[r_pos] := temp; aktualisieren; markiere(clGreen, l_pos); markiere(clGreen, r_pos); //<-------- Hier Application.ProcessMessages; sleep(1000); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:36 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