AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi problem beim sortieren einer verketteten liste
Thema durchsuchen
Ansicht
Themen-Optionen

problem beim sortieren einer verketteten liste

Ein Thema von arest · begonnen am 4. Aug 2009 · letzter Beitrag vom 6. Aug 2009
Antwort Antwort
arest

Registriert seit: 27. Sep 2005
Ort: Frankfurt
62 Beiträge
 
Delphi 6 Personal
 
#1

problem beim sortieren einer verketteten liste

  Alt 4. Aug 2009, 22:39
abend allerseits, hab nen problem mit meiner sortieren funktion für eine verkettete liste... hab eine liste, die über eingabefelder mit diverse daten gefüllt wird, welche ich nun über radiobuttons sortieren möchte. hab das sehr ähnlich bei einem anderen projekt schon mal gemacht und da hat es wunderbar funktioniert, jetzt streikt es allerdings :/ hier erst mal was vom code:

Delphi-Quellcode:
//********************************SORTIEREN FUNKTION*********************************
   //nachname
   procedure TForm1.RadioButton1Click(Sender: TObject);
   begin
      nachname:=true;
      vorname:=false;
      kategorie:=false;
      geburtstag:=false;
      sortieren;
   end;
   //vorname
   procedure TForm1.RadioButton2Click(Sender: TObject);
   begin
      nachname:=false;
      vorname:=true;
      kategorie:=false;
      geburtstag:=false;
      sortieren;
   end;
   //kategorie
   procedure TForm1.RadioButton5Click(Sender: TObject);
   begin
      nachname:=false;
      vorname:=false;
      kategorie:=true;
      geburtstag:=false;
      sortieren;
   end;
   //geburtstag
   procedure TForm1.RadioButton6Click(Sender: TObject);
   begin
      nachname:=false;
      vorname:=false;
      kategorie:=false;
      geburtstag:=true;
      sortieren;
   end;
   procedure TForm1.RadioButton3Click(Sender: TObject);
   begin
      sortieren;
   end;
   procedure TForm1.RadioButton4Click(Sender: TObject);
   begin
      sortieren;
   end;
   //sortieren
   procedure sortieren;
   begin
      lauf:=TKnoten.Init;
      if (anfang.nachfolger<>ende)
      then begin
              anfang2:=TKnoten.Init;
              ende2:=TKnoten.Init;
              anfang2.nachfolger:=ende2;
              ende2.vorgaenger:=anfang2;
              if (nachname=true)
              then begin
                      lauf:=anfang;
                      repeat lauf:=lauf.nachfolger;
                         neu2:=TKnoten.Init;
                         neu2.Daten:=lauf.Daten;
                         lauf2:=anfang2;
                         if (Form1.RadioButton3.Checked=true)
                         then begin
                                 repeat lauf2:=lauf2.nachfolger;
                                 until (lauf2.Daten.nachname > neu2.Daten.nachname) or (lauf2=ende2);
                              end;
                         if (Form1.RadioButton4.Checked=true)
                         then begin
                                 repeat lauf2:=lauf2.nachfolger;
                                 until (lauf2.Daten.nachname < neu2.Daten.nachname) or (lauf2=ende2);
                              end;
                         lauf2.vorgaenger.nachfolger:=neu2;
                         neu2.vorgaenger:=lauf2.vorgaenger;
                         lauf2.vorgaenger:=neu2;
                         neu2.nachfolger:=lauf2;
                      until (lauf=ende.vorgaenger);
                      anfang:=anfang2;
                      ende:=ende2;
                      knoteneinlesen;
                   end;
              if (vorname=true)
              then begin
                      lauf:=anfang;
                      repeat lauf:=lauf.nachfolger;
                         neu2:=TKnoten.Init;
                         neu2.Daten:=lauf.Daten;
                         lauf2:=anfang2;
                         if (Form1.RadioButton3.Checked=true)
                         then begin
                                 repeat lauf2:=lauf2.nachfolger;
                                 until (lauf2.Daten.vorname > neu2.Daten.vorname) or (lauf2=ende2);
                              end;
                         if (Form1.RadioButton4.Checked=true)
                         then begin
                                 repeat lauf2:=lauf2.nachfolger;
                                 until (lauf2.Daten.vorname < neu2.Daten.vorname) or (lauf2=ende2);
                              end;
                         lauf2.vorgaenger.nachfolger:=neu2;
                         neu2.vorgaenger:=lauf2.vorgaenger;
                         lauf2.vorgaenger:=neu2;
                         neu2.nachfolger:=lauf2;
                      until (lauf=ende.vorgaenger);
                      anfang:=anfang2;
                      ende:=ende2;
                      knoteneinlesen;
                   end;
              if (kategorie=true)
              then begin
                      lauf:=anfang;
                      repeat lauf:=lauf.nachfolger;
                         neu2:=TKnoten.Init;
                         neu2.Daten:=lauf.Daten;
                         lauf2:=anfang2;
                         if (Form1.RadioButton3.Checked=true)
                         then begin
                                 repeat lauf2:=lauf2.nachfolger;
                                 until (lauf2.Daten.kategorie > neu2.Daten.kategorie) or (lauf2=ende2);
                              end;
                         if (Form1.RadioButton4.Checked=true)
                         then begin
                                 repeat lauf2:=lauf2.nachfolger;
                                 until (lauf2.Daten.kategorie < neu2.Daten.kategorie) or (lauf2=ende2);
                              end;
                         lauf2.vorgaenger.nachfolger:=neu2;
                         neu2.vorgaenger:=lauf2.vorgaenger;
                         lauf2.vorgaenger:=neu2;
                         neu2.nachfolger:=lauf2;
                      until (lauf=ende.vorgaenger);
                      anfang:=anfang2;
                      ende:=ende2;
                      knoteneinlesen;
                   end;
              if (geburtstag=true)
              then begin
                      lauf:=anfang;
                      repeat lauf:=lauf.nachfolger;
                         neu2:=TKnoten.Init;
                         neu2.Daten:=lauf.Daten;
                         lauf2:=anfang2;
                         if (Form1.RadioButton3.Checked=true)
                         then begin
                                 repeat lauf2:=lauf2.nachfolger;
                                 until (lauf2.Daten.geburtstag > neu2.Daten.geburtstag) or (lauf2=ende2);
                              end;
                         if (Form1.RadioButton4.Checked=true)
                         then begin
                                 repeat lauf2:=lauf2.nachfolger;
                                 until (lauf2.Daten.geburtstag < neu2.Daten.geburtstag) or (lauf2=ende2);
                              end;
                         lauf2.vorgaenger.nachfolger:=neu2;
                         neu2.vorgaenger:=lauf2.vorgaenger;
                         lauf2.vorgaenger:=neu2;
                         neu2.nachfolger:=lauf2;
                      until (lauf=ende.vorgaenger);
                      anfang:=anfang2;
                      ende:=ende2;
                      knoteneinlesen;
                   end;
      end;
   end;
das interessante ist, dass die sortierung auf nachname und vorname reagiert und soweit funktioniert, allerdings das auf/absteigend was über radiobutton3/4 abgefragt würde komplett ignoriert! knoteneinlesen ist eine procedure um die neu sortierte liste in einen listview zu schreiben (funktioniert fehlerfrei)

any ideas?
  Mit Zitat antworten Zitat
Benutzerbild von Chemiker
Chemiker

Registriert seit: 14. Aug 2005
1.858 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: problem beim sortieren einer verketteten liste

  Alt 4. Aug 2009, 23:14
Hallo arest,

ist eine etwas eigenwillige Formatierung des Quellcodes.

Ich kann jetzt nichts zu Deinem konkreten Problem beitragen.

Allerdings, sollte man die Abfragen nicht auf TRUE abfragen.

z.B.:

Delphi-Quellcode:
if (nachname=true)
              then begin
besser:

Delphi-Quellcode:
if nachname then
begin

Delphi-Quellcode:
if (Form1.RadioButton4.Checked=true)
                         then begin
besser:

Delphi-Quellcode:
if Form1.RadioButton3.Checked then
begin
  repeat
    lauf2:=lauf2.nachfolger;
  until ((lauf2.Daten.nachname > neu2.Daten.nachname) or (lauf2=ende2));
end;
Wenn der Ausdruck nach until komplett ausgewertet werden soll, sollte der Ausdruck komplett in eine Klammer gestellt werden.

Bis bald Chemiker
wer gesund ist hat 1000 wünsche wer krank ist nur einen.
  Mit Zitat antworten Zitat
arest

Registriert seit: 27. Sep 2005
Ort: Frankfurt
62 Beiträge
 
Delphi 6 Personal
 
#3

Re: problem beim sortieren einer verketteten liste

  Alt 4. Aug 2009, 23:30
danke der antwort, aber das ändert nichts am problem...
  Mit Zitat antworten Zitat
Benutzerbild von Chemiker
Chemiker

Registriert seit: 14. Aug 2005
1.858 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: problem beim sortieren einer verketteten liste

  Alt 4. Aug 2009, 23:38
Hallo arest,

Dir ist aber bewusst, dass wenn man die Klammer nicht setzt, unter umständen nur der erste Teil der Abfrage ausgewertet wird?

Bis bald Chemiker
wer gesund ist hat 1000 wünsche wer krank ist nur einen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.167 Beiträge
 
Delphi 12 Athens
 
#5

Re: problem beim sortieren einer verketteten liste

  Alt 4. Aug 2009, 23:55
bei dem Code selber seh icht grad nicht so durch, als daß ich jetzt och Fehler finde (ist aber auch schon spät)

für alle deine RadioButons (1-6) kannst du auch eine einzige OnClick-Prozedur nutzen (einfach allein zuweisen)

das lauf2=ende2 würde ich zuerst abfragen, bevor ich auf lauf2 für dür den/die Vergleich(e) zugreife

dann nutzt du in der Sortieren-Funktion durcheinander diese Booleans und die CheckBoxen.
wenn du schon diese Booleans hast, warum nutzt du dann nicht nur diese?

und das mit dem True wurde schon gesagt.

ich hoff mal ich hab's auf das Wichtigste reduziert (an der Funktionsweise sollte sich nicht viel geändert haben, abgesehn vom lauf2=ende2)
Delphi-Quellcode:
procedure TForm1.RadioButtonClick(Sender: TObject);
begin
   nachname := RadioButton1.Checked;
   vorname := RadioButton2.Checked;
   kategorie := RadioButton5.Checked;
   geburtstag := RadioButton6.Checked;
   richtung := RadioButton3.Checked;
   // RadioButton4 ist in der 3 enthalten, da ja wohl das Negative
   sortieren;
end;

procedure sortieren;
begin
   lauf:=TKnoten.Init;
   if (anfang.nachfolger<>ende)
   then begin
      anfang2:=TKnoten.Init;
      ende2:=TKnoten.Init;
      anfang2.nachfolger:=ende2;
      ende2.vorgaenger:=anfang2;

      lauf:=anfang;
      repeat
         lauf:=lauf.nachfolger;
         neu2:=TKnoten.Init;
         neu2.Daten:=lauf.Daten;
         lauf2:=anfang2;
         repeat
            lauf2:=lauf2.nachfolger;
         until (lauf2=ende2)
            or ( richtung and nachname and (lauf2.Daten.nachname > neu2.Daten.nachname))
            or (not richtung and nachname and (lauf2.Daten.nachname < neu2.Daten.nachname))
            or ( richtung and vorname and (lauf2.Daten.vorname > neu2.Daten.vorname))
            or (not richtung and vorname and (lauf2.Daten.vorname < neu2.Daten.vorname))
            or ( richtung and kategorie and (lauf2.Daten.kategorie > neu2.Daten.kategorie))
            or (not richtung and kategorie and (lauf2.Daten.kategorie < neu2.Daten.kategorie))
            or ( richtung and geburtstag and (lauf2.Daten.geburtstag > neu2.Daten.geburtstag))
            or (not richtung and geburtstag and (lauf2.Daten.geburtstag < neu2.Daten.geburtstag));
         lauf2.vorgaenger.nachfolger:=neu2;
         neu2.vorgaenger:=lauf2.vorgaenger;
         lauf2.vorgaenger:=neu2;
         neu2.nachfolger:=lauf2;
      until (lauf=ende.vorgaenger);
      anfang:=anfang2;
      ende:=ende2;
      knoteneinlesen;
   end;
end;
ich glaub so müßte man es noch kürzen können
Delphi-Quellcode:
repeat
   lauf2:=lauf2.nachfolger;
until (lauf2=ende2)
   or (nachname and ((lauf2.Daten.nachname < neu2.Daten.nachname) xor richtung))
   or (vorname and ((lauf2.Daten.vorname < neu2.Daten.vorname) xor richtung))
   or (kategorie and ((lauf2.Daten.kategorie < neu2.Daten.kategorie) xor richtung))
   or (geburtstag and ((lauf2.Daten.geburtstag < neu2.Daten.geburtstag) xor richtung));

nja, zumindestens isses jetzt etwas übersichtlicher und man findet womöglich den Fehler schneller,
außerdem nur ein Sortier-Code, statt 4 = 75% weniger Fehlerquellen



um wieviele Listenelemente handelt es sich denn?
ich hab es mir letztens einfach gemacht

- Elemente gezählt
- dynamisches Array für die Elemente angelegt
- Array gefüllt
- in dem Array sortiert
- und dann über das Array neu neu verkettet

so geht das sortieren sogar etwas schneller, da man direkt über den Arrayindex sortieren und agieren kann
und sich wärend des Sortierens sich nicht um die Verknüfungen kümmern muß


[add]
sind RadioButton 3 und 4 unabhängig von den Anderen?
Gruppe 1 = 1, 2, 5 & 6
Gruppe 2 = 3 & 4

denn wenn in auch nur einer der Gruppen kein Button gecheckt ist, dann macht deine Version nix
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Carsten1234

Registriert seit: 9. Apr 2008
Ort: Vechelde
178 Beiträge
 
Delphi 8 Professional
 
#6

Re: problem beim sortieren einer verketteten liste

  Alt 5. Aug 2009, 09:46
Zitat von himitsu:
ich hab es mir letztens einfach gemacht
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#7

Re: problem beim sortieren einer verketteten liste

  Alt 5. Aug 2009, 14:08
Also abgesehen davon, daß ich durch die Original Sourcen nicht so richtig durchsteige,
-ich hätte z.B. gerne die record-Definition gesehen-

Hinter RadoButton3 und Radiobutton4 werden keine Parameter gesetzt, wie z.B. hier
Delphi-Quellcode:
begin
      nachname:=false;
      vorname:=false;
      kategorie:=false;
      geburtstag:=true;
      sortieren;
   end;
In der Sortierroutine werden diese Werte aber abgefragt, das sieht mir sehr nach dem Ausnutzen von Seiteneffekten aus, da würde ich mich nicht wundern, wenn das Sortieren nicht klappt.

Gruß
K-H
  Mit Zitat antworten Zitat
arest

Registriert seit: 27. Sep 2005
Ort: Frankfurt
62 Beiträge
 
Delphi 6 Personal
 
#8

Re: problem beim sortieren einer verketteten liste

  Alt 6. Aug 2009, 11:10
erst mal großes dankeschön an himitsu! die funktion so wie du sie umgeschrieben hast, funktioniert soweit, allerdings nur soweit wie meine bisher auch :/ sie ist deutlich übersichtlicher und das fehler finden ist dadurch sicherlich leichter radiobutton 1,2,5,6 sind in einer gruppe und 3,4 in einer anderen, wobei zu jeder zeit jeweils einer ausgewählt ist (vom formcreate an), d.h. daran kann es nicht liegen! weiterhin missachtet wird aufwärts/abwärts sortieren, sowie die sortierung nach geb/kategorie.... aus dem grund mal ne allgemeine frage dazu: wenn ich geburtstag als string reinsetzte, dann ist es klar, dass er nicht nach z.b. erst jahr, dann monat und dann tag sortiert, sondern einfach die zahlenwerte der reihe nach durchgeht. er müsste aber dennoch eigentlich zumindest in der hinsicht sortieren oder? d.h. ein geburtstag vom 21.03.1975 müsste dann einfach nach dem 13.03.1975 oder was auch immer gesetzt werden, da er einfach von vorne nach hinten den string durcharbeitet und 2 größer 1 ist, oder? warum zum geier reagiert er darauf also nicht? ich habe mit durchlauf per einzelanweisungen geprüft, ob die daten alle richtig eingelesen werden, was absolut der fall ist.... alles strings, alle gefüllt, keine fehler bis dahin! hier kurz die geforderte record methode...

Delphi-Quellcode:
type TDaten=record
   nachname,vorname,strasse,hausnummer,postleitzahl,wohnort,telefonhome,telefonhandy,telefonoffice,email,geburtstag,kategorie:string[50];
end;

type TKnoten=Class(TObject)
   Daten:TDaten;
   vorgaenger,nachfolger:TKnoten;
   Constructor Init;
end;

anschließend:
Delphi-Quellcode:
Constructor TKnoten.Init;
begin
   Daten.nachname:='';
   Daten.vorname:='';
   Daten.strasse:='';
   Daten.hausnummer:='';
   Daten.postleitzahl:='';
   Daten.wohnort:='';
   Daten.telefonhome:='';
   Daten.telefonhandy:='';
   Daten.telefonoffice:='';
   Daten.email:='';
   Daten.geburtstag:='';
   Daten.kategorie:='';
   vorgaenger:=NIL;
   nachfolger:=NIL;
end;

ins formcreate folgendes:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
   anfang:=TKnoten.Init;
   ende:=TKnoten.Init;
   anfang.nachfolger:=ende;
   ende.vorgaenger:=anfang;
   Radiobutton1.Checked:=true;
   Radiobutton3.Checked:=true;
   nachname:=true;
   vorname:=false;
   kategorie:=false;
   geburtstag:=false;
   richtung:=true;
end;

über eingabefelder werden die variablen gefüllt, wie bereits erwähnt problemfrei und anschließend über die sortieren funktion sortiert (habe jetzt die von himitsu drin). wo liegt die logik, dass nur vor/nachname funktionieren, obwohl keinerlei unterschiede in variablen/herangehensweise in der sortierfunktion vorliegen?! und warum reagiert die kacke auch in himitsu's version nicht auf auf/absteigend??
  Mit Zitat antworten Zitat
arest

Registriert seit: 27. Sep 2005
Ort: Frankfurt
62 Beiträge
 
Delphi 6 Personal
 
#9

Re: problem beim sortieren einer verketteten liste

  Alt 6. Aug 2009, 13:42
habe es noch mal ein wenig umgeschrieben, jedoch in dem sinne nicht wirklich was geändert, und jetzt funktioniert es einwandfrei.... danke für die bemügungen an alle! code im vorherigen eintrag gleich geblieben (record/knoten/formcreate) aber im sortierenbereich noch mal geändert wie folgt:

Delphi-Quellcode:
//********************************SORTIEREN FUNKTION*********************************
   //ausgewaehlt
   procedure ausgewaehlt;
   begin
      nachname:=Form1.RadioButton1.Checked;
      vorname:=Form1.RadioButton2.Checked;
      kategorie:=Form1.RadioButton5.Checked;
      geburtstag:=Form1.RadioButton6.Checked;
      richtung:=Form1.RadioButton3.Checked;
   end;
   //nachname
   procedure TForm1.RadioButton1Click(Sender: TObject);
   begin
      ausgewaehlt;
      sortieren;
   end;
   //vorname
   procedure TForm1.RadioButton2Click(Sender: TObject);
   begin
      ausgewaehlt;
      sortieren;
   end;
   //kategorie
   procedure TForm1.RadioButton5Click(Sender: TObject);
   begin
      ausgewaehlt;
      sortieren;
   end;
   //geburtstag
   procedure TForm1.RadioButton6Click(Sender: TObject);
   begin
      ausgewaehlt;
      sortieren;
   end;
   procedure TForm1.RadioButton3Click(Sender: TObject);
   begin
      ausgewaehlt;
      sortieren;
   end;
   procedure TForm1.RadioButton4Click(Sender: TObject);
   begin
      ausgewaehlt;
      sortieren;
   end;


//sortieren
procedure sortieren;
begin
   lauf:=TKnoten.Init;
   if (anfang.nachfolger<>ende)
   then begin
      anfang2:=TKnoten.Init;
      ende2:=TKnoten.Init;
      anfang2.nachfolger:=ende2;
      ende2.vorgaenger:=anfang2;

      lauf:=anfang;
      repeat
         lauf:=lauf.nachfolger;
         neu2:=TKnoten.Init;
         neu2.Daten:=lauf.Daten;
         lauf2:=anfang2;
         repeat
            lauf2:=lauf2.nachfolger;
         until (lauf2=ende2)
            or ( richtung and nachname and (lauf2.Daten.nachname > neu2.Daten.nachname))
            or (not richtung and nachname and (lauf2.Daten.nachname < neu2.Daten.nachname))
            or ( richtung and vorname and (lauf2.Daten.vorname > neu2.Daten.vorname))
            or (not richtung and vorname and (lauf2.Daten.vorname < neu2.Daten.vorname))
            or ( richtung and kategorie and (lauf2.Daten.kategorie > neu2.Daten.kategorie))
            or (not richtung and kategorie and (lauf2.Daten.kategorie < neu2.Daten.kategorie))
            or ( richtung and geburtstag and (lauf2.Daten.geburtstag > neu2.Daten.geburtstag))
            or (not richtung and geburtstag and (lauf2.Daten.geburtstag < neu2.Daten.geburtstag));
         lauf2.vorgaenger.nachfolger:=neu2;
         neu2.vorgaenger:=lauf2.vorgaenger;
         lauf2.vorgaenger:=neu2;
         neu2.nachfolger:=lauf2;
      until (lauf=ende.vorgaenger);
      anfang:=anfang2;
      ende:=ende2;
      knoteneinlesen;
   end;
end;
THX!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:31 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz