Autor Beitrag
Bestzeller
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: Mi 08.04.09 14:04 
Hi,
Ich hab eine Liste mit den Prozeduren Keller und Schlange erstellt und möchte nun ein beliebiges Listenelement löschen. Der Record enthält nur eine Integerzahl und die Prozedure dazu ist auch schon fast fertig. Jetzt muss ich nur noch bestimmte Fälle ausschließen, daher die Frage : Wie prüfe ich ob die gesuchte Zahl im ersten Listenelement ist?
Muss ich jetzt in der Suche einen Counter mitlaufen lassen oder geht es auch anders?
Logikmensch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 390

Win XP
Delphi 2007 Prof., XE2, XE5
BeitragVerfasst: Do 09.04.09 12:35 
Für eine exakte Antwort ist die Frage zu ungenau. Was für ein Typ Liste ist es denn? Ein TList-Abkömmling, eine TStringList, oder ein dynamisches Array?

_________________
Es gibt keine Probleme - nur Lösungen!
pigfacejoe
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 332
Erhaltene Danke: 1

Win 10, Ubuntu
Delphi,Javascript, PHP, Java, Python
BeitragVerfasst: Do 09.04.09 13:02 
Deine Liste sollte eine Zeigervariable pfirst oder pErstes (p für Pointer)besitzen. Mit dieser Zeigervariable prüfst du einfach, ob diese deinen Suchstring enthält.
Beispiel:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
function Tliste.loesche(x:string):boolean;
var erg:boolean;
begin
erg:=false;
if pfirst^.data=x then 
begin
if pfirst^.pnext<>nil then
begin
pfirst^.pnext^.pprev:=nil//Wenn du eine doppelt verkettete Liste hast
pfirst:=pfirst^.pnext;
end ;
dispose(pfirst);
erg:=true;
end
else 
....
end;


Ich weiß zwar nicht, ob ich dein Problem richtig gedeutet hab, aber ich hoffe das hilft dir. Falls nicht, zeig doch mal die Deklaration deiner Liste und beschreib mal genauer, was tun willst.
Gruß
Max
Gruß
Max
Bestzeller Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: Do 09.04.09 17:28 
Das Objekt ist wie folgt deklariert:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
type

  Zeiger=^element;
  element=record
    z:integer;
    next:zeiger;
  end;

  Tliste=class(Tobject)
    Head,Tail,Fund,tmp:zeiger;
    check:boolean;
    suchzahl,anzahl:integer;
    Constructor init;
    procedure Keller(zahl:integer);
    procedure Schlange(zahl:integer);
    procedure Pop(var zahl:integer);
    procedure anzeigen(lb:tlistbox);
    procedure suchen(k:zeiger);
    procedure loeschen;
   end;


Und so sieht die Prozedur löschen bei mir aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure tliste.loeschen;

begin

 tmp:=Head ;

 suchen(Head);

// <If anzahl = 1 then pop>
// <IF Fund  = 1. Zahl then pop>
// <If Fund.next = nil then dispose Fund und tail eine höher setzen>
 While tmp^.next <> Fund do tmp:=tmp^.next;

 tmp^.next:=Fund^.next;

 dispose(Fund);

end;


Funktioniert im Moment nur bei einer Liste die mehr als 2 Elemente hat und wenn die Suchzahl sich im mittleren Teil befindet. Wenn jetzt aber die Suchzahl im ersten Element ist , muss ich den Kopf (Zeiger) eine heruntersetzen , aber wie überprüf ich den überhaupt ob es das erste Element ist? wenn es das letzte Element wär könnte man ja einfach mit if
abfragen, weil der Nächste auf Nil zeigt.
Mr_Emre_D
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 114
Erhaltene Danke: 14



BeitragVerfasst: Fr 10.04.09 13:48 
Warum verwendest du keine Doppelt-Verkettung?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
PElement = ^TElement;
TElement = record
  DataBlub: String;
  Previous, Next: PElement;
end;

//in der Klasse
  Liste, tmp: PElement;  // der erste Listeneintrag hat als Previous = NIL und der Letzte als Next = NIL

// Bsp: Deine Liste zeigt heirhin
//             |
// Element - Element - Element - Element - Element
// Wenn du es löschen willst musst du zuerst dem vorigen sagen, dass sein Nächster der Nächste vom aktuellen Datensatz ist und dem Nächsten(vom akutellen Datensatz) sagen, dass sein Voriger der Vorige vom akt. D. ist ...

Liste^.Previous^.Next := Liste^.Next;
Liste^.Next^.Previous := Liste^.Previous;

// Somit hättest du die Pointer verbogen
// Nun kannst du den Datensatz, den du mit New angelegt hast, Disposen:
tmp := Liste;
Liste := Liste^.Next // je nach dem (next, prev)...
Dispose( tmp );


MfG
Bestzeller Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: Fr 10.04.09 15:49 
user profile iconMr_Emre_D hat folgendes geschrieben Zum zitierten Posting springen:
Warum verwendest du keine Doppelt-Verkettung?


Haben wir im Unterricht noch nicht gehabt. Aber Danke jetzt weiß ich eben mehr. :)

Ps: Frohe Ostern!^^
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Fr 10.04.09 16:21 
warum so umständlich?
machs rekursiv
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure tliste.loeschen(var list:zeiger);
var tmp:zeiger;
begin

if(list<>nilthen begin
  if(list^.z=suchzahl) then begin
  tmp:=list;
  list:=list^.next;
  dispose(tmp);
  end else loeschen(list^.next);
end;

end;


bei listen geht das bearbeiten rekursiv immer besser, weil eine liste rekursiv definiert ist.
ansonsten doppelt verkettete liste nehmen oder viel aufwand mit temporären variablem machen.

BTW:
du solltest deine typ-namen besser wählen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
  pZeiger=^Telement;
  Telement=record
    z:integer;
    next:pZeiger;
  end

alle typen mit großem T vorne versehen und pointer mit kleinem p vorne (nur ein auszug aus der namensgebung)
sonst passiert es schnell, dass du eine variable "element" nennst...
Mr_Emre_D
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 114
Erhaltene Danke: 14



BeitragVerfasst: Fr 10.04.09 16:56 
user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
warum so umständlich?
machs rekursiv

Warum den Stack auslasten wenn man ihn schonen kann? :P
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Fr 10.04.09 17:04 
sagen wir so: es ist für die schule wenn ich das richtig verstanden habe,
und da ist es sehr wahrscheinlich, dass es bonuspunkte für die rekursive variante gibt.
selbst an der uni wird (erstmal) die rekursive version gelehrt. also warum nicht benutzen?