home *** CD-ROM | disk | FTP | other *** search
- (*-------------------------------------------------------------------------*)
- (* *)
- (* Amiga Oberon Library Module: BinaryTrees Date: 02-Nov-92 *)
- (* *)
- (* © 1992 by Fridtjof Siebert *)
- (* *)
- (*-------------------------------------------------------------------------*)
-
- MODULE BinaryTrees;
-
- IMPORT BT * := BasicTypes;
-
- TYPE
-
- Node * = POINTER TO NodeDesc;
- NodeDesc * = RECORD (BT.COMPAREABLEDesc)
- l * : Node;
- r * : Node;
- END;
-
-
- Root * = POINTER TO RootDesc;
- RootDesc * = RECORD (BT.COLLECTIONDesc)
- root * : Node;
- addOk * : BOOLEAN;
- remOk * : BOOLEAN;
- END;
-
-
- PROCEDURE (a: Node) Find*(root: Root): LONGINT;
- (* Diese Prozedur wird von Find() verwendet.
- * Ihr Ergebnis ist
- * = 0, wenn a das gesuchte Element ist
- * < 0, wenn a < dem gesuchten Element ist
- * > 0, wenn a > dem gesuchten Element ist
- *)
- BEGIN HALT(20) END Find;
-
-
- (*-------------------------------------------------------------------------*)
-
-
- (*------ Create: ------*)
-
-
- PROCEDURE Create*(): Root;
- (*
- * alloziert neuen, leeren AVL-Baum
- *)
-
- VAR
- r: Root;
-
- BEGIN
- NEW(r); RETURN r;
- END Create;
-
-
- (*------ Add: ------*)
-
-
- PROCEDURE (root: Root) Add* (node: BT.ANY);
-
- (* fügt node in den Baum ein.
- * War ein gleichnamiger Knoten bereits im Baum, wird der Baum nicht
- * verändert und roo.addOk auf FALSE gesetzt.
- *
- * require
- * node IS Node
- *
- *)
-
- PROCEDURE Search(VAR n: Node);
-
- VAR c: LONGINT;
-
- BEGIN
- IF n=NIL THEN (* neues Element einfügen: *)
- n := node(Node);
- n.l := NIL; n.r := NIL;
- root.addOk := TRUE;
- ELSE
- c := n.Compare(node(Node));
- IF c>0 THEN
- Search(n.l);
- ELSIF c<0 THEN
- Search(n.r);
- END;
- END;
- END Search;
-
- BEGIN
- root.addOk := FALSE;
- Search(root.root);
- END Add;
-
-
- (*------ Find: ------*)
-
-
- PROCEDURE (root: Root) Find* (): Node;
-
- (* Sucht denjenigen Knoten, für den Root.Find das Ergebnis 0 liefert und
- gibt seine Adresse oder NIL zurück. *)
-
- VAR
- n: Node;
- c: LONGINT;
-
- BEGIN
- n := root.root;
- LOOP
- IF n=NIL THEN RETURN NIL END;
- c := n.Find(root);
- IF c<0 THEN n := n.r
- ELSIF c>0 THEN n := n.l
- ELSE RETURN n END;
- END;
- END Find;
-
-
- (*------ Remove: ------*)
-
-
- PROCEDURE (root: Root) Remove* (node: BT.ANY);
-
- (* Entfernt node aus dem Baum.
- * War node nicht im Baum, wird der Baum nicht verändert und roo.remOk auf FALSE
- * gesetzt.
- *
- * require
- * node IS Node
- *)
-
- PROCEDURE Rem(VAR n: Node);
-
- VAR
- c: LONGINT;
- New,Q: Node;
-
- BEGIN
- IF n # NIL THEN
- c := n.Compare(node(Node));
- IF c>0 THEN Rem(n.l)
- ELSIF c<0 THEN Rem(n.r)
- ELSE
- root.remOk := TRUE;
- IF n.r=NIL THEN n := n.l
- ELSIF n.l=NIL THEN n := n.r
- ELSE
- Q := n.l;
- WHILE Q.r#NIL DO Q := Q.r END;
- Q.r := n.r;
- n := n.l;
- END;
- END;
- END;
- END Rem;
-
- BEGIN
- root.remOk := FALSE;
- Rem(root.root);
- END Remove;
-
-
- (*-------------------------------------------------------------------------*)
-
-
- PROCEDURE (tree: Root) nbElements * (): LONGINT;
- (* returns the number of elements within tree.
- *)
-
- PROCEDURE CountElements(n: Node): LONGINT;
- BEGIN
- IF n=NIL THEN RETURN 0
- ELSE RETURN CountElements(n.l) + CountElements(n.r) + 1
- END;
- END CountElements;
-
- BEGIN
- RETURN CountElements(tree.root);
- END nbElements;
-
-
- PROCEDURE (tree: Root) isEmpty * (): BOOLEAN;
- (* TRUE if tree is empty
- *)
-
- BEGIN
- RETURN tree.root=NIL;
- END isEmpty;
-
-
- PROCEDURE (tree: Root) Do * (p: BT.DoProc; par: BT.ANY);
- (* calls p(x,par) for every element x stored within tree.
- * the tree is travesed in infix order.
- * par passes some additional information to p. par is not touched by Do.
- *)
-
- PROCEDURE do(n: Node);
-
- BEGIN
- IF n#NIL THEN
- do(n.l);
- p(n,par);
- do(n.r);
- END;
- END do;
-
- BEGIN
- do(tree.root);
- END Do;
-
-
- (*------ DoBackward: ------*)
-
-
- PROCEDURE (root: Root) DoBackward* (proc: BT.DoProc; par: BT.ANY);
-
- (* calls p(x,par) for every element x stored within tree.
- * the tree is travesed in reverse order.
- * par passes some additional information to p. par is not touched by Do.
- *)
-
- PROCEDURE DoBkwd(n: Node);
-
- BEGIN
- IF n#NIL THEN
- DoBkwd(n.r);
- proc(n,par);
- DoBkwd(n.l);
- END;
- END DoBkwd;
-
- BEGIN
- DoBkwd(root.root);
- END DoBackward;
-
-
- (*------ Dispose: ------*)
-
-
- PROCEDURE (root: Root) Dispose*;
-
- (* Ruft DISPOSE() mit allen Elementen des Baumes auf, gibt also seinen
- * gesamten Speicher frei.
- *)
-
- (* $IFNOT GarbageCollector *)
-
- PROCEDURE Disp(n: Node);
-
- BEGIN
- IF n#NIL THEN
- Disp(n.l);
- Disp(n.r);
- DISPOSE(n);
- END;
- END Disp;
-
- (* $END *)
-
- BEGIN
-
- (* $IFNOT GarbageCollector *)
-
- Disp(root.root);
-
- (* $ELSE *)
-
- root.root := NIL;
-
- (* $END *)
-
- END Dispose;
-
-
- (*-------------------------------------------------------------------------*)
-
-
- END BinaryTrees.
-
-
-
-