Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
196
Task/AVL-tree/Component-Pascal/avl-tree-1.pas
Normal file
196
Task/AVL-tree/Component-Pascal/avl-tree-1.pas
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
MODULE RosettaAVLTrees;
|
||||
|
||||
(* An implementation of persistent AVL Trees *)
|
||||
|
||||
TYPE
|
||||
Order = ABSTRACT RECORD END;
|
||||
Tree* = POINTER TO Node;
|
||||
Node* = ABSTRACT RECORD (Order)
|
||||
left, right: Tree;
|
||||
height: INTEGER
|
||||
END; (* Contains the left and right child nodes and the height of the node *)
|
||||
|
||||
Out* = ABSTRACT RECORD END; (* Used for output by the `Draw` procedure *)
|
||||
|
||||
Void = RECORD (Order) END; (* Used by the `Ordered` procedure *)
|
||||
|
||||
(* The following abstract procedures must be implemented by a user of `Node` *)
|
||||
(* They must be implemented correctly for the AVL tree to work *)
|
||||
|
||||
(* Compares one node with another and returns a boolean value based on which is less *)
|
||||
PROCEDURE (IN n: Order) Less- (IN m: Node): BOOLEAN, NEW, ABSTRACT;
|
||||
(* Compares one node with another and returns a boolean value based on which is more *)
|
||||
PROCEDURE (IN n: Order) More- (IN m: Node): BOOLEAN, NEW, ABSTRACT;
|
||||
(* Creates a new root node *)
|
||||
PROCEDURE (IN n: Node) Alloc- (): Tree, NEW, ABSTRACT;
|
||||
|
||||
(* Returns TRUE if n is in the tree t, FALSE otherwise *)
|
||||
PROCEDURE (IN n: Node) Lookup* (t: Tree): BOOLEAN, NEW;
|
||||
BEGIN
|
||||
IF t = NIL THEN RETURN FALSE END;
|
||||
IF n.Less(t) THEN RETURN n.Lookup(t.left) END;
|
||||
IF n.More(t) THEN RETURN n.Lookup(t.right) END;
|
||||
RETURN TRUE
|
||||
END Lookup;
|
||||
|
||||
(* Returns the height of the AVL tree t *)
|
||||
PROCEDURE Height (t: Tree): INTEGER;
|
||||
BEGIN
|
||||
IF t = NIL THEN RETURN 0 END;
|
||||
RETURN t.height
|
||||
END Height;
|
||||
|
||||
(* Creates and returns a new Node with the given children *)
|
||||
PROCEDURE (IN n: Node) New (left, right: Tree): Tree, NEW;
|
||||
VAR t: Tree;
|
||||
BEGIN
|
||||
t := n.Alloc(); (* Create a new root node *)
|
||||
t.left := left; t.right := right; (* set the children *)
|
||||
(* set the height of the node based on its children *)
|
||||
t.height := MAX(Height(left), Height(right)) + 1;
|
||||
RETURN t
|
||||
END New;
|
||||
|
||||
(* Returns the difference in height between the left and right children of a node *)
|
||||
PROCEDURE Slope (l, r: Tree): INTEGER;
|
||||
BEGIN RETURN Height(l) - Height(r) END Slope;
|
||||
|
||||
(* Returns an AVL tree if it is right-heavy *)
|
||||
PROCEDURE (IN n: Node) BalL (l, r: Tree): Tree, NEW;
|
||||
BEGIN
|
||||
IF Slope(l, r) = - 2 THEN
|
||||
IF Slope(r.left, r.right) = 1 THEN
|
||||
RETURN r.left.New(n.New(l, r.left.left),
|
||||
r.New(r.left.right, r.right))
|
||||
END;
|
||||
RETURN r.New(n.New(l, r.left), r.right)
|
||||
END;
|
||||
RETURN n.New(l, r)
|
||||
END BalL;
|
||||
|
||||
(* Returns an AVL tree if it is left-heavy *)
|
||||
PROCEDURE (IN n: Node) BalR (l, r: Tree): Tree, NEW;
|
||||
BEGIN
|
||||
IF Slope(l, r) = 2 THEN
|
||||
IF Slope(l.left, l.right) = - 1 THEN
|
||||
RETURN l.right.New(l.New(l.left, l.right.left),
|
||||
n.New(l.right.right, r))
|
||||
END;
|
||||
RETURN l.New(l.left, n.New(l.right, r))
|
||||
END;
|
||||
RETURN n.New(l, r)
|
||||
END BalR;
|
||||
|
||||
(* Returns the AVL tree t with the node n *)
|
||||
PROCEDURE (IN n: Node) Insert* (t: Tree): Tree, NEW;
|
||||
BEGIN
|
||||
IF t = NIL THEN RETURN n.New(NIL, NIL) END;
|
||||
IF n.Less(t) THEN RETURN t.BalR(n.Insert(t.left), t.right) END;
|
||||
IF n.More(t) THEN RETURN t.BalL(t.left, n.Insert(t.right)) END;
|
||||
RETURN t
|
||||
END Insert;
|
||||
|
||||
(* Returns the leftmost node of the non-empty tree t *)
|
||||
PROCEDURE (t: Tree) Head (): Tree, NEW;
|
||||
BEGIN
|
||||
IF t.left = NIL THEN RETURN t END;
|
||||
RETURN t.left.Head()
|
||||
END Head;
|
||||
|
||||
(* Returns the rightmost node of the non-empty tree t *)
|
||||
PROCEDURE (t: Tree) Last (): Tree, NEW;
|
||||
BEGIN
|
||||
IF t.right = NIL THEN RETURN t END;
|
||||
RETURN t.right.Last()
|
||||
END Last;
|
||||
|
||||
(* Returns the AVL tree t without the leftmost node *)
|
||||
PROCEDURE (IN t: Node) Tail* (): Tree, NEW;
|
||||
BEGIN
|
||||
IF t.left = NIL THEN RETURN t.right END;
|
||||
RETURN t.BalL(t.left.Tail(), t.right)
|
||||
END Tail;
|
||||
|
||||
(* Returns the AVL tree t without the rightmost node *)
|
||||
PROCEDURE (IN t: Node) Init* (): Tree, NEW;
|
||||
BEGIN
|
||||
IF t.right = NIL THEN RETURN t.left END;
|
||||
RETURN t.BalR(t.left, t.right.Init())
|
||||
END Init;
|
||||
|
||||
(* Returns the AVL tree t without node n *)
|
||||
PROCEDURE (IN n: Node) Delete* (t: Tree): Tree, NEW;
|
||||
BEGIN
|
||||
IF t = NIL THEN RETURN NIL END;
|
||||
IF n.Less(t) THEN RETURN t.BalL(n.Delete(t.left), t.right) END;
|
||||
IF n.More(t) THEN RETURN t.BalR(t.left, n.Delete(t.right)) END;
|
||||
IF Slope(t.left, t.right) = 1 THEN
|
||||
RETURN t.left.Last().BalL(t.left.Init(), t.right)
|
||||
END;
|
||||
IF t.right = NIL THEN RETURN t.left END;
|
||||
RETURN t.right.Head().BalR(t.left, t.right.Tail())
|
||||
END Delete;
|
||||
|
||||
(* The following procedures are used for debugging *)
|
||||
|
||||
PROCEDURE (IN n: Void) Less- (IN m: Node): BOOLEAN;
|
||||
BEGIN RETURN TRUE END Less;
|
||||
|
||||
PROCEDURE (IN n: Void) More- (IN m: Node): BOOLEAN;
|
||||
BEGIN RETURN TRUE END More;
|
||||
|
||||
(* Returns TRUE if the AVL tree t is ordered, FALSE otherwise *)
|
||||
PROCEDURE Ordered* (t: Tree): BOOLEAN;
|
||||
VAR void: Void;
|
||||
|
||||
PROCEDURE Bounded (IN lo, hi: Order; t: Tree): BOOLEAN;
|
||||
BEGIN
|
||||
IF t = NIL THEN RETURN TRUE END;
|
||||
RETURN lo.Less(t) & hi.More(t) &
|
||||
Bounded(lo, t, t.left) & Bounded(t, hi, t.right)
|
||||
END Bounded;
|
||||
|
||||
BEGIN RETURN Bounded(void, void, t) END Ordered;
|
||||
|
||||
(* The following abstract procedures must be implemented by a user of `Out` *)
|
||||
|
||||
(* Writes a string *)
|
||||
PROCEDURE (IN o: Out) Str- (s: ARRAY OF CHAR), NEW, ABSTRACT;
|
||||
(* Writes an integer *)
|
||||
PROCEDURE (IN o: Out) Int- (i: INTEGER), NEW, ABSTRACT;
|
||||
(* Writes a new-line *)
|
||||
PROCEDURE (IN o: Out) Ln-, NEW, ABSTRACT;
|
||||
(* Writes a node *)
|
||||
PROCEDURE (IN o: Out) Node- (IN n: Node), NEW, ABSTRACT;
|
||||
|
||||
(* Writes a tree (rotated) *)
|
||||
PROCEDURE (IN o: Out) Draw* (t: Tree), NEW;
|
||||
|
||||
PROCEDURE Bars (bars, bar: ARRAY OF CHAR);
|
||||
BEGIN
|
||||
IF LEN(bars + bar) # 0 THEN o.Str(bars + "+--") END
|
||||
END Bars;
|
||||
|
||||
PROCEDURE Do (lBar, rBar, bars: ARRAY OF CHAR; t: Tree);
|
||||
BEGIN
|
||||
IF t = NIL THEN Bars(bars, lBar); o.Str("|"); o.Ln
|
||||
ELSIF (t.left = NIL) & (t.right = NIL) THEN
|
||||
Bars(bars, lBar); o.Node(t); o.Ln
|
||||
ELSE
|
||||
Do("| ", " ", bars + rBar, t.right);
|
||||
o.Str(bars + rBar + "|"); o.Ln;
|
||||
Bars(bars, lBar); o.Node(t);
|
||||
IF Slope(t.left, t.right) # 0 THEN
|
||||
o.Str(" ["); o.Int(Slope(t.left, t.right)); o.Str("]")
|
||||
END;
|
||||
o.Ln;
|
||||
o.Str(bars + lBar + "|"); o.Ln;
|
||||
Do(" ", "| ", bars + lBar, t.left)
|
||||
END
|
||||
END Do;
|
||||
|
||||
BEGIN
|
||||
Do("", "", "", t)
|
||||
END Draw;
|
||||
|
||||
END RosettaAVLTrees.
|
||||
24
Task/AVL-tree/Component-Pascal/avl-tree-2.pas
Normal file
24
Task/AVL-tree/Component-Pascal/avl-tree-2.pas
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
DEFINITION RosettaAVLTrees;
|
||||
|
||||
TYPE
|
||||
Tree = POINTER TO Node;
|
||||
Node = ABSTRACT RECORD (Order)
|
||||
(IN n: Node) Alloc- (): Tree, NEW, ABSTRACT;
|
||||
(IN n: Node) Delete (t: Tree): Tree, NEW;
|
||||
(IN t: Node) Init (): Tree, NEW;
|
||||
(IN n: Node) Insert (t: Tree): Tree, NEW;
|
||||
(IN n: Node) Lookup (t: Tree): BOOLEAN, NEW;
|
||||
(IN t: Node) Tail (): Tree, NEW
|
||||
END;
|
||||
|
||||
Out = ABSTRACT RECORD
|
||||
(IN o: Out) Draw (t: Tree), NEW;
|
||||
(IN o: Out) Int- (i: INTEGER), NEW, ABSTRACT;
|
||||
(IN o: Out) Ln-, NEW, ABSTRACT;
|
||||
(IN o: Out) Node- (IN n: Node), NEW, ABSTRACT;
|
||||
(IN o: Out) Str- (s: ARRAY OF CHAR), NEW, ABSTRACT
|
||||
END;
|
||||
|
||||
PROCEDURE Ordered (t: Tree): BOOLEAN;
|
||||
|
||||
END RosettaAVLTrees.
|
||||
63
Task/AVL-tree/Component-Pascal/avl-tree-3.pas
Normal file
63
Task/AVL-tree/Component-Pascal/avl-tree-3.pas
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
MODULE RosettaAVLTreesUse;
|
||||
|
||||
IMPORT Set := RosettaAVLTrees, Log := StdLog;
|
||||
|
||||
TYPE
|
||||
Height = RECORD (Set.Node) height: INTEGER END;
|
||||
(* Note that Set.Node already contains an integer field `height`. *)
|
||||
(* It does not cause a duplicate field error as it is hidden from this module *)
|
||||
|
||||
Out = RECORD (Set.Out) END; (* Used for output by the `Draw` procedure *)
|
||||
|
||||
(* The following three procedures are implemented here for use by Set.Node *)
|
||||
|
||||
(* Compares one node with another and returns a boolean value based on which is less *)
|
||||
PROCEDURE (IN h: Height) Less- (IN n: Set.Node): BOOLEAN;
|
||||
BEGIN RETURN h.height < n(Height).height END Less;
|
||||
|
||||
(* Compares one node with another and returns a boolean value based on which is more *)
|
||||
PROCEDURE (IN h: Height) More- (IN n: Set.Node): BOOLEAN;
|
||||
BEGIN RETURN h.height > n(Height).height END More;
|
||||
|
||||
(* Creates a new root node *)
|
||||
PROCEDURE (IN h: Height) Alloc- (): Set.Tree;
|
||||
VAR r: POINTER TO Height;
|
||||
BEGIN NEW(r); r.height := h.height; RETURN r END Alloc;
|
||||
|
||||
(* The following four procedures are implemented here for use by Set.Out *)
|
||||
|
||||
(* Writes a string *)
|
||||
PROCEDURE (IN o: Out) Str- (s: ARRAY OF CHAR);
|
||||
BEGIN Log.String(s) END Str;
|
||||
|
||||
(* Writes an integer *)
|
||||
PROCEDURE (IN o: Out) Int- (i: INTEGER);
|
||||
BEGIN Log.IntForm(i, Log.decimal, 0, ' ', Log.hideBase) END Int;
|
||||
|
||||
(* Writes a new-line *)
|
||||
PROCEDURE (IN o: Out) Ln-; BEGIN Log.Ln END Ln;
|
||||
|
||||
(* Writes a node *)
|
||||
PROCEDURE (IN o: Out) Node- (IN n: Set.Node);
|
||||
BEGIN
|
||||
Log.IntForm(n(Height).height, Log.decimal, 0, ' ', Log.hideBase)
|
||||
END Node;
|
||||
|
||||
PROCEDURE Use*;
|
||||
TYPE BAD = POINTER TO Height;
|
||||
VAR h: Height; hs, save: Set.Tree; i: INTEGER; o: Out;
|
||||
BEGIN
|
||||
h.height := 10; hs := h.Insert(hs);
|
||||
FOR i := 0 TO 9 DO h.height := i; hs := h.Insert(hs) END;
|
||||
o.Draw(hs); Log.Ln; Log.Ln;
|
||||
save := hs;
|
||||
FOR i := 0 TO 9 DO h.height := i; hs := h.Delete(hs) END;
|
||||
o.Draw(hs); Log.Ln; Log.Ln;
|
||||
o.Draw(save); Log.Ln; Log.Ln; (* Tree demonstrates persistence *)
|
||||
ASSERT(Set.Ordered(save)); (* This ASSERT succeeds *)
|
||||
save(BAD).height := 11; (* UNSAFE STATEMENT *)
|
||||
o.Draw(save);
|
||||
ASSERT(Set.Ordered(save)) (* This ASSERT fails *)
|
||||
END Use;
|
||||
|
||||
END RosettaAVLTreesUse.
|
||||
Loading…
Add table
Add a link
Reference in a new issue