Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Frage zu linearer Liste (https://www.delphipraxis.net/128551-frage-zu-linearer-liste.html)

Churchy 1. Feb 2009 10:30


Frage zu linearer Liste
 
Hi!
Da ich für meine mündliche Matura (=Reifeprüfung) ein Spezialgebiet mit dem Thema "Lineare Listen und Binäre Bäume" schreiben muss und da bisher lediglich das Einfügen funktioniert, dachte ich ich schau mal ob mir hier wer helfen kann, da ich auch keine Turtorials gefunden habe die mir weiter geholfen haben.

Ich habe bei jedem Button dazugeschrieben was dieser Button machen soll.
Hier ist der Quelltext:

Delphi-Quellcode:
unit Programm;

interface

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

type
  PListe = ^TListe;      //Pointer deklariert

  TListe = record        //Liste deklariert
    key: Integer;
    next: PListe;
    text: String;
  end;
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    ListBox1: TListBox;
    Button2: TButton;
    Button3: TButton;
    Edit2: TEdit;
    Button4: TButton;
    Button5: TButton;
    Button6: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Liste: PListe;
  q: PListe;
  i: integer;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);          //Leere Liste
begin
  liste := nil;
  i:= 0;
end;

procedure TForm1.Button1Click(Sender: TObject);       //Button für Listenerstellung am Kopf
begin
  new(q);
  i := i+1;
  q.text := edit1.Text;
  q.next := liste;
  q.key := i;
  liste := q;
end;

procedure TForm1.Button2Click(Sender: TObject);      //Button für Listenausgabe
begin
  while liste <> nil do begin
    Listbox1.Items.Add(inttostr(liste.key) + ': ' + liste.text);
    liste := liste.next;
  end;
end;

procedure TForm1.Button4Click(Sender: TObject);      // Button für Listenerstellung am Ende
var h:PListe;
begin
  i := i+1;
  if liste = nil then begin
    new(liste);
    liste.text := edit1.Text;
    Liste.key := i;
    Liste.next := nil;
  end else begin
  h := liste;
  while h.next <> nil do begin
    h := h.next;
  end;
  new(q);
  h.next:= q;
  q.text := edit1.Text;
  q.key := i;
  q.next := nil;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);               //vor Key hinzufügen
var x: integer;
begin
  x:= strtoint(edit2.Text);
  while liste <> nil do begin
    if liste.key <> x then begin
      liste :=liste.next;
    end else begin
      i := i+1;
      new(q);
      q := liste;
      liste.key := i;
      liste.text := edit1.Text;
      liste.next := q;
    end;
  end;
end;

procedure TForm1.Button5Click(Sender: TObject);               //hinter Key hinzufügen
var x: integer;
begin
  x := strtoint(edit2.Text);
  while liste <> nil do begin
    if liste.key <> x then begin
      liste := liste.next;
    end else begin
      i := i+1;
      new(q);
      q.next := liste.next;
      liste.next := q;
      q.key := i;
      q.text := edit1.Text;
    end;
  end;
end;


procedure TForm1.Button6Click(Sender: TObject);               //Key löschen
  var x: integer;
      h: Pliste;
begin
  x := strtoint(edit2.Text);
  while liste <> nil do begin
    if liste.key <> x then begin
      liste := liste.next;
    end else begin
      h := liste.next;
      liste.next := h.next;
      liste.text := h.text;
      liste.key := h.key;
    end;
  end;
end;

end.
Also zurück zu meiner Frage: Weiß jemand warum die Buttons "vor Key hinzufügen", "nach Key hinzufügen" und "Key löschen" nicht funktionieren?
(Ich habe deswegen den ganzen Quelltext kopiert damit ihr wisst wie ich bisher gearbeitet habe ;) )
Ich hoffe auf baldige Antwort.
Mit freundlichen Grüßen
Churchy

Meflin 1. Feb 2009 10:52

Re: Frage zu linearer Liste
 
WAS funktioniert denn nicht? Fehlermeldung? Tut was, aber nicht so wie gewünscht? Passiert garnix?

Würde die Fehlersuche etwas eingrenzen :glaskugel:

Churchy 1. Feb 2009 11:01

Re: Frage zu linearer Liste
 
Es passiert gar nichts. ;)
Keine Fehlermeldung kein gar nichts.
Würd mich ja über ne Fehlermeldung freuen so könnt ich wenigstens explizit nach dem Fehler suchen, aber so habe ich keine Ahnung, da ich mir auch aufgezeichnet habe was passiert und irgendwie müsste es so funktionieren, aber das tut es nicht. : - /

himitsu 1. Feb 2009 11:24

Re: Frage zu linearer Liste
 
Delphi-Quellcode:
    liste := liste.next;
du solltest bei deinen Schleifen nicht die "Start"-Variable nutzen, denn so änderst du diese und deine List verschwindet, da diese Variable danach auf nil steht

Delphi-Quellcode:
templist := liste;
while templiste <> nil do begin

  templiste := templiste.next;
end;

Klaus01 1. Feb 2009 11:29

Re: Frage zu linearer Liste
 
... und noch das Zeigertutorial vom Ghostwalker

Grüße
Klaus

Churchy 1. Feb 2009 12:03

Re: Frage zu linearer Liste
 
Zitat:

Zitat von Klaus01
... und noch das Zeigertutorial vom Ghostwalker

Grüße
Klaus

Thx für das Tut.
Werd mal das versuchen was ihr beiden über mir gesagt habt. ;)

omata 1. Feb 2009 12:19

Re: Frage zu linearer Liste
 
dann eben nicht... [Anhang gelöscht]

himitsu 1. Feb 2009 13:02

Re: Frage zu linearer Liste
 
@omata: es wäre schon nett, wenn du wenigstens kurz sagen könntest, was in deinem Anhang drin ist.

Meflin 1. Feb 2009 15:53

Re: Frage zu linearer Liste
 
Zitat:

Zitat von omata
dann eben nicht... [Anhang gelöscht]

Lol?! Was geht eigentlich mit dir ab? Spielst du jetzt "bei jedem Wort beleidigte Leberwurst" :gruebel:

Churchy 1. Feb 2009 17:34

Re: Frage zu linearer Liste
 
Ähm ja O.o
Also so weit hab ichs ja wies in diesem Tut steht eigtl. (ja schon oben) und was genau das templiste bringen soll versteh ich nicht :-/
Muss ich dabei sämtliche Liste in templiste umschreiben oder nur die in den Schleifen

himitsu 1. Feb 2009 17:58

Re: Frage zu linearer Liste
 
So richtig wie im Tut isses nicht wirklich :zwinker:

In Liste steht doch das erste Element deiner Liste,
wenn du nun diese Variable in einer Schleife direkt benutzt und deren Inhalt (per Liste := Liste.next; ) änderst, dann änderst du doch auch deren Inhalt
und wenn die schleife bis NIL ( while tempListe <> nil do ) geht, dann steht danach NIL in Liste drin und deine Liste ist leer.

du mußt also zur Benutzung deren Wert in eine 2 Variable speichern, deren Inhalt sich problemlos ändern kann ... somit bleibt der Inhalt der Variable Liste unverändert.
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);      //Button für Listenausgabe
var tempListe: PListe;
begin
  tempListe := Liste;
  while tempListe <> nil do begin
    Listbox1.Items.Add(inttostr(tempListe.key) + ': ' + tempListe.text);
    tempListe := tempListe.next;
  end;
end;
PS: die Variable i könnte einen verständlicheren Namen vertragen (z.B. NaechsteID, LetzteID, NextID oder so)

PSS: die Variable q ist doch eigentlich nur 'ner temoräre lokale Variable und sollte deswegen direkt in den Prozeduren (Button1Click, Button3Click, Button4Click und Button5Click) definiert sein.


dein q entspricht hlp : PMYELEMENT; in dem Tut
und tempListe entspricht sozusagen dem wrk : PMYELEMENT;

DeddyH 1. Feb 2009 18:00

Re: Frage zu linearer Liste
 
Ich bin nicht sicher, ob Du das Prinzip einer einfach verketteten Liste verstanden hast. Was Du auf jeden Fall brauchst, ist ein Zeiger auf das erste Element als globale Variable oder privates Feld des Formulars. Dieser ist bei Programmstart nil, da es ja noch kein Element gibt. Fügst Du nun ein neues Element am Listenende ein, musst Du zuallererst prüfen, ob dieser Zeiger belegt ist. Wenn nicht, bildet das neue Element den Anfang, sein Nachfolger ist dementsprechend nil. War das erste Element bereits belegt, musst Du den Zeigern folgen, um das letzte Element zu ermitteln. Dessen Nachfolger wird dann das neue Element, dessen Nachfolger dann wieder mit nil belegt wird.

Churchy 1. Feb 2009 18:20

Re: Frage zu linearer Liste
 
Achso ok danke ;)
Das is mal gut zu wissen ^^

So jetzt hab ich alles einmal geändert und mittlerweile hängt sich Delphi auf sobald ich.

Der nicht funktionierende Quelltext sieht so aus:

Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);               //vor Key hinzufügen
var x: integer;
    templiste, q: PListe;
begin
  x:= strtoint(edit2.Text);
  templiste := liste;
  while templiste <> nil do begin
    if templiste.key = x then begin
      i := i+1;
      new(q);
      q := liste;
      templiste.key := i;
      templiste.text := edit1.Text;
      templiste.next := q;
    end;
    templiste := templiste.next;
  end;
end;

procedure TForm1.Button5Click(Sender: TObject);               //hinter Key hinzufügen
var x: integer;
     templiste, q: PListe;
begin
  x := strtoint(edit2.Text);
  templiste := liste;
  while templiste <> nil do begin
    if templiste.key <> x then begin
      i := i+1;
      new(q);
      q.next := templiste.next;
      templiste.next := q;
      q.key := i;
      q.text := edit1.Text;
    end;
    templiste := templiste.next;
  end;
end;

Klaus01 1. Feb 2009 19:52

Re: Frage zu linearer Liste
 
Habe mal einige Kommentare eingefügt.

Delphi-Quellcode:
    procedure TForm1.Button5Click(Sender: TObject);               //hinter Key hinzufügen
var x: integer;
     templiste, q: PListe;
begin
  x := strtoint(edit2.Text);
  templiste := liste;

  // Was bezweckst Du hiermit?
  while templiste <> nil do begin
    // wenn temListe.key = x ist
    // dann wird an der aktuellen Position
    // ein Element eingefügt.
    // Soll das so sein?
    if templiste.key <> x then begin
      i := i+1;
      new(q);
      // wenn das neue Element an das Ende der Liste
      // angefügt wird, dann sollte q.next := nil
      q.next := templiste.next;
      templiste.next := q;
      q.key := i;
      q.text := edit1.Text;
    end;
    templiste := templiste.next;
  end;
end;
Eine Endlosschleife würde darauf hindeutem, dass in der Liste das letzte Element nicht auf nil zeigt.

Habe mal noch etwa nachgedacht.
Willst Du ein neues Element (q) vor bzw. nach einem bestehenden Element einfügen?
Wenn dem so sein sollte, dann solltest Du mehrere Fälle unterscheiden.

a) Du willst vor dem ersten Element ein Element einfügen,
dann ändert sich die Adresse des ersten Elementes (Ancker)
Delphi-Quellcode:
new(q);
q.next:=liste;
Ancker := q;
q...
b)Du willst nach dem letzen Element ein Element anhängen.
Delphi-Quellcode:
new(q);
q.next := nil;
liste.next := q;
q...
b) Du willst innerhalb der Liste ein Element einfügen
Dazu brauchst Du dann noch einen Buffer für das
Element vor dem aktuellen Element.
Delphi-Quellcode:
new(q);
buf.next := q;
q.next := liste;
q...

Grüße
Klaus

Churchy 1. Feb 2009 21:56

Re: Frage zu linearer Liste
 
k danke an alle die mir geholfen haben, ich glaube mittlerweile hab ich das Prinzip der Zeiger und somit der Listen verstanden :)
Einzig und allein vor einem Key einfügen endet weiterhin in einer (mir nicht erklärbaren) Endlosschleife :-/

@Klaus01: Jo es soll an dieser Stelle eingefügt werden und ich hab mittlerweile den Fehler gefunden (das ungleich einfach mit = vertauschen... :wall: ).

Also nochmal zum vor dem Key hinzufügen:
ich ordne jedem Listenelement eine Zahl zu und eben auf genau diese will ich hier zugreifen. Soll heißen ich will je nachdem vor (funktioniert nicht) oder nach (funktioniert) diesem Element einfügen.

Der Quelltext sieht so aus:

Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);               //vor Key hinzufügen
var x: integer;
    templiste, buffer, q: PListe;
begin
  x:= strtoint(edit2.Text);
  templiste := liste;
  while templiste <> nil do begin
    if templiste.key = x then begin
      i := i+1;
      new(q);
      q := templiste;
      templiste.key := i;
      templiste.text := edit1.Text;
      templiste.next := q;
    end;
    templiste := templiste.next;
  end;
end;

himitsu 1. Feb 2009 22:09

Re: Frage zu linearer Liste
 
was mir auf den ersten Blick auffällt ... du überschreibst das grade erst erstellte Q mit templist

Delphi-Quellcode:
new(q);
q := templiste;

Hawkeye219 1. Feb 2009 22:16

Re: Frage zu linearer Liste
 
Herzlich willkommen in der Delphi-PRAXiS, Churchy.

Wenn du diese Seite gelesen hast, wirst du sehen, dass du bei der einfach verketteten Liste zum Einfügen von Elementen einen Hilfszeiger benötigst.

Gruß Hawkeye

Churchy 1. Feb 2009 23:15

Re: Frage zu linearer Liste
 
Dankeschön :)
Mittlerweile funktioniert das ganze Programm und ich bin euch echt dankbar für die Hilfe ^^
Kann von mir aus geschlossen werden ;)
MfG Churchy


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:50 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