|
[Home |
Algorithmen] |
|
Zeigerverkettete Listen mit Pointern gelten oft als der Höhepunkt der Informatik in der Schule. Zweifellos gehört das Konzept zu den unverzichtbaren Inhalten. Über die Frage, ob im Unterricht harte Zeigerprobleme codiert werden müssen, gehen die Meinungen auseinander. Im Rahmen von OOP (jedenfalls, wenn alles Objekte sein sollen), kann man sich Zeigersemantik kaum vorstellen. JAVA als klassenbasierte Hochsprache kokettiert mit dem völligen Verzicht auf Pointer-Semantik wegen der relativen Gefährlichkeit. Da viele Probleme am elegantesten durch Zeiger-Strukturen gelöst werden können, wird das klassische Konzept Pointer-->Record durch Referenz-->Klasse gelöst, also durch eine selbstreferenzielle Assoziation des Elementtyps (rekursiv). Die nachfolgende rudimentäre Klasse Liste bildet in DELPHI die in Java übliche Programmierung nach. Der Typ TInhalt ist ein wenig 'dirty' und überflüssig, wenn man nur Objekte verwaltet, erlaubt aber auch beliebige Typen als Inhalt ohne weitere Anpassung des Codes oder Typcasting beim lesenden Zugriff. UNIT uRListe;
(* ******************************************************************** *)
(* K L A S S E : TElement, TListe *)
(* -------------------------------------------------------------------- *)
(* Version : 0.9 - Rohversion, nix abgefangen *)
(* Autor : S. Spolwig, 2005 *)
(* Beschreibung: uRListe vereint die Klassen TElement u. TListe als *)
(* zeigerverkettetene lineare Liste, die zusammen *)
(* betrachtet werden sollen. *)
(* Die etwas merkwürdige Konstruktion ist der Versuch, *)
(* ohne Pointer auszukommen, dabei aber die Grundsätze von*)
(* OOP einzuhalten. Nach einer Anregung von D. Garmann, *)
(* http://www.gymnasium-odenthal.de *)
(* Compiler : Delphi 7.0 *)
(* Aenderungen : 0.9 30-MAR-05 *)
(* ******************************************************************** *)
INTERFACE
// =======================================================================
type
TInhalt = TObject; // hier ändern für andere oder POINTER fuer alles
// --------------------------------------------------------------------
TElement = class (TObject)
private
Inhalt : TInhalt;
ZeigerNext, // Zeiger auf nächstes Element - kein POINTER!
ZeigerPrev : TElement; // voriges
public
constructor Create (data : TInhalt);
end;
// --------------------------------------------------------------------
TListe = class (TObject)
protected
zFirstElememt, // der Ankerpunkt
zActualElement : TElement; // wo man steht
public
constructor Create;
procedure First;
procedure Next ;
procedure Last ;
procedure Append (data : TInhalt);
function GetInhalt : TInhalt;
function GetLen : integer ;
function IsEmpty : boolean;
private
end;
(* -------------------- B e s c h r e i b u n g -------------------------
Oberklasse :
Bezugsklassen : ........... import:
Methoden
--------
...
Get...
Auftrag: Attribut aus dem Objekt lesen
vorher : Objekt ist vorhanden
nachher: -
First
Auftrag : Listenmarke (Zeiger) auf den Listenanfang setzen
vorher : Die Liste ist vorhanden
nachher : Aktuelle Position ist das 1. Element
Ist die Liste leer , geschieht nichts
...
--------------------------------------------------------------------- *)
IMPLEMENTATION
// ====================================================================
constructor TElement.Create (data : TInhalt);
// --------------------------------------------------------------------
begin
inherited Create;
Inhalt := data;
ZeigerNext := NIL; // dahinter kommt noch nix
ZeigerPrev := NIL;
end;
// ====================================================================
constructor TListe.Create;
// --------------------------------------------------------------------
begin
inherited Create;
zFirstElememt := NIL; // am Anfang leer
zActualElement := NIL;
end;
procedure TListe.First;
// --------------------------------------------------------------------
begin
zActualElement := zFirstElememt;
end;
procedure TListe.Next ;
// --------------------------------------------------------------------
begin
if (NOT IsEmpty) AND (zActualElement.ZeigerNext <> NIL)
then zActualElement := zActualElement.ZeigerNext;
end;
procedure TListe.Last;
// --------------------------------------------------------------------
begin
if (NOT IsEmpty) AND (zActualElement.ZeigerNext <> NIL)
then
begin
zActualElement := zActualElement.ZeigerNext;
Last;
end;
end;
function TListe.IsEmpty : boolean;
// --------------------------------------------------------------------
begin
Result := (zFirstElememt = NIL);
end;
procedure TListe.Append (data : TInhalt);
// --------------------------------------------------------------------
var
NewElem : TElement;
begin
NewElem := TElement.Create(data); // neues El. erzeugen
if IsEmpty
then
begin
zFirstElememt := NewElem;
zActualElement := NewElem;
end
else
begin
Last;
zActualElement.ZeigerNext := NewElem;
zActualElement := NewElem;
end;
end;
function TListe.GetInhalt : TInhalt;
// --------------------------------------------------------------------
begin
Result := zActualElement.Inhalt;
end;
function TListe.GetLen : integer;
// --------------------------------------------------------------------
var
l : integer;
zHilf : TElement;
begin
l := 0;
zHilf := zFirstElememt;
while zHilf <> NIL do
begin
zHilf := zHilf.ZeigerNext;
inc(l);
end;
Result := l;
end;
// ------- usw. ---
END.
|