Entwickler-Ecke

Sonstiges (Delphi) - Bubblesort funktioniert nicht ganz


Sputyyy - Do 24.03.11 12:52
Titel: Bubblesort funktioniert nicht ganz
Hallo Leute!!
Ich habe eine Frage. Ich habe ein Bubblesort programmiert und es funktioniert auch fast. Doch es werden statt Zahlen nur "0" ausgegeben. Bitte um Hilfe :D


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:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TBubblesortierer = class(TForm)
    Ueberschrift1: TLabel;
    Anzahl_label: TLabel;
    Anzahl_edit: TEdit;
    erstesmemo: TMemo;
    zweitesmemo: TMemo;
    fuellen_btn: TButton;
    ordnen_btn: TButton;
    schliessen_btn: TButton;
    procedure fuellen_btnClick(Sender: TObject);
    procedure ordnen_btnClick(Sender: TObject);
    procedure schliessen_btnClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Bubblesortierer: TBubblesortierer;

implementation

{$R *.dfm}

procedure tausche (var a,b : real);
var x:real;
begin
x:=a;
a:=b;
b:=x;
end;

procedure bubblesort (var aa: array of real; n1, n2 : Integer);
var i: Integer;
fertig: Boolean;
begin
repeat
  fertig:=true;
  for i := n1 to n2 - 1 do
  begin
  If aa[i]>aa[i+1then begin
  tausche(aa[i], aa[i+1]);
  fertig:=false;
  end;
  end;
until fertig;
end;
procedure zeige(mm: Tmemo; aa:array of real);
var i: integer;
begin
  mm.Lines.Clear;
  for i := 0 to Length(aa) - 1 do   mm.Lines.Add(FloatToStr(aa[i]));
end;

procedure TBubblesortierer.ordnen_btnClick(Sender: TObject);
var aa: array of real;
n, i : Integer;
begin
 n:= StrToInt(Anzahl_edit.Text);
 setlength(aa,n);
 for i := 0 to n - 1 do       aa[i]:= StrToFloat(erstesmemo.lines[i]);
 bubblesort(aa, 0, n-1);
 zeige(zweitesmemo,aa);
end;

procedure TBubblesortierer.schliessen_btnClick(Sender: TObject);
begin
close;
end;


procedure TBubblesortierer.fuellen_btnClick(Sender: TObject);
var
i, anzahl: Integer;
aa: array of real;
begin
anzahl:= StrToInt(Anzahl_edit.text);
setlength(aa, anzahl);
for i := 0 to Anzahl - 1 do tausche (aa[i], aa[random(Anzahl)]);
zeige(erstesmemo,aa)
end;
end.


Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt


Delphi-Laie - Do 24.03.11 16:02

user profile iconSputyyy hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe eine Frage.


Welche? Ich finde keine.

user profile iconSputyyy hat folgendes geschrieben:
habe ein Bubblesort programmiert und es funktioniert auch fast. Doch es werden statt Zahlen nur "0" ausgegeben.


Wenn es nur Nullen ausgibt, dann funktioniert es nicht fast, sondern überhaupt nicht. Nein, Du hast es nicht programmiert, sondern das bisher nur versucht. Aber es soll(te) auch Dir gelingen, denn Bubblesort ist einer der primitivsten Sortieralgorithmen überhaupt.

Das eigentliche Bubblesort besteht aus zweien, ineinander verschachtelten Schleifen. Du brachtest das Kunststück fertig, das in zwei bis drei verschiedene Routinen (bubblesort, TBubblesortierer.ordnen und evtl. auch noch TBubblesortierer.fuellen) zu verpacken. Warum dermaßen kompliziert? Ich sähe da auch nicht mehr durch. Bringe das eigentliche Sortieren erst einmal in ein Unterprogramm, bis es funktioniert und verkompliziere es dann soweit wie nötig (! d.h., nicht wie möglich)!


jackle32 - Do 24.03.11 16:15

Hallo zusammen.

Ich hab mir mal die Arbeit gemacht und deinen Code laufen lassen. Ergebnis: es würde mich wundern wenn er mehr als Nullen ausgeben würde.
Das erste Problem ist schon das Füllen des Arrays. Das machst du nämlich nirgends. Das einzige was gemacht wird mit der komischen "tauschen" Funktion, so wie du sie anwendest ist die Nullen gegeneinander austauschen.

Dein eigentlicher Sortieralgorithmus scheint zu funktionieren, wenn er auch verdammt unübersichtlich geschrieben ist.
Kleiner Tipp: wenn es dir nur um den Bubblesort geht, definiere "aa" global dadurch wird einiges einfacher.

Ansonsten kann ich user profile iconDelphi-Laie nur zustimmen. Vereinfache deinen Code!!

Gruß,

Jack


Delphi-Laie - Do 24.03.11 16:18

user profile iconjackle32 hat folgendes geschrieben Zum zitierten Posting springen:
ch hab mir mal die Arbeit gemacht und deinen Code laufen lassen. Ergebnis: es würde mich wundern wenn er mehr als Nullen ausgeben würde.
Das erste Problem ist schon das Füllen des Arrays. Das machst du nämlich nirgends. Das einzige was gemacht wird mit der komischen "tauschen" Funktion, so wie du sie anwendest ist die Nullen gegeneinder austauschen.


Mist, diese Idee kam mir auch gerade, daß es gar nicht an falscher Sortierung, sondern an einer fehlerhaften Ausgangsmenge liegen könnte. Da war jemand schneller.

Nur Nullen lassen sich nämlich durchaus auch Sortieren (wenn auch nicht im engeren Sinne).


HenryHux - Do 24.03.11 22:43

Mir fällt auf, dass du den Bereich übergibst.
Doch wozu?
Brauchst du nicht!
Änder am besten die Parameter nur auf den Array und arbeite mit high() und low().

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure bubblesort (var aa: array of real);
var i: Integer;
fertig: Boolean;
begin
repeat
  fertig:=true;
  for i := low(aa) to high(aa) do


Falls es nicht klappen sollte guck mal hier : http://www.stefan-baur.de/cs.algo.bubblesort.html
Und wenn es nicht unbedingt der BubbleSort sein muss, dann hier http://www.stefan-baur.de/cs.algo.quicksort.html

Lg


jaenicke - Fr 25.03.11 06:04

user profile iconjackle32 hat folgendes geschrieben Zum zitierten Posting springen:
Kleiner Tipp: wenn es dir nur um den Bubblesort geht, definiere "aa" global dadurch wird einiges einfacher.
Ich hoffe du meinst ein privates Feld unter private des Formulars.

user profile iconjackle32 hat folgendes geschrieben Zum zitierten Posting springen:
Das erste Problem ist schon das Füllen des Arrays. Das machst du nämlich nirgends.
Öhm, wieso?
user profile iconSputyyy hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TBubblesortierer.ordnen_btnClick(Sender: TObject);
var aa: array of real;
n, i : Integer;
begin
 n:= StrToInt(Anzahl_edit.Text);
 setlength(aa,n);
 for i := 0 to n - 1 do       aa[i]:= StrToFloat(erstesmemo.lines[i]);
 bubblesort(aa, 0, n-1);
 zeige(zweitesmemo,aa);
end;
Bei mir funktioniert der Code auch problemlos (abgesehen vom Anzeige-Button, der eben nur leere Daten anzeigt). :nixweiss:

Wenn aber nur fuellen_btnClick statt ordnen_btnClick ausgeführt wird, sind es logischerweise nur Nullen. Aber das ist ja ohnehin nicht der Knopf zum Sortieren.


jackle32 - Fr 25.03.11 10:54

Moin zusammen,

Zitat:
user profile iconjackle32 hat folgendes geschrieben :
Zitat:
Das erste Problem ist schon das Füllen des Arrays. Das machst du nämlich nirgends.

Öhm, wieso?


Okay er füllt das Array mit den Werten die im Memo1 stehen. Aber was steht im Normalfall in Memo1, die Zahlen die in der Funktion fuellen_btnClick in das Array geschrieben werden. Und in dieser besagen Funktion macht er nichts anderes als die Zahlen (nur Nullen) zufällig zu vertauschen.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TBubblesortierer.fuellen_btnClick(Sender: TObject);
 vari, anzahl: Integer;
 aa: array of real;
 beginanzahl:= StrToInt(Anzahl_edit.text);
 setlength(aa, anzahl);
 for i := 0 to Anzahl - 1 do tausche (aa[i], aa[random(Anzahl)]); 
 zeige(erstesmemo,aa)
end;


Diese Zeile macht also nicht wirklich Sinn und es wird das Array nie mit anderen Werten als Nullen gefüllt!!
Natürlich kann ich nach dem Klick auf Füllen die Werte manuell im Memo ändern, was aber denke ich nicht die Idee war, bzw. wenn dies die Idee war, macht die Zeile in fuellen_btnClick noch weniger Sinn als jetzt schon.

Daher kann ich nur meine Aussage wiederholen, das Sortieren ansich funktioniert nur das Array wird nie sinnvoll gefüllt!!

Zum Themas globale Variable ist ja jetzt für diesen Test egal ob ich das in private der Form zuordne oder unter var komplett global. Es ist ja nur so, dass ich mir in den einzelnen Funktionen das Erzeugen spare und dadurch der Code für dieses Beispiel übersichtlicher wird. Wie das in größeren Projekten zu handhaben ist, ist ja noch ein anderes Thema, hier würde es aber die Übersichtlichkeit erhöhen und die wesentlichen Funktionen die für den Sortieralgorithmus nötig sind besser darstellen.

Gruß,
Jack