type BinaryStringTree = {
setLeft(_:BinaryStringTree)->Void
setRight(_:BinaryStringTree)->Void
clear->Void
isEmpty->Boolean
isLeaf->Boolean
isLeftChild->Boolean
isRightChild->Boolean
isRoot->Boolean
height->Number
depth->Number
getString->String
getLeftChild->BinaryStringTree
getRightChild->BinaryStringTree
getParent->BinaryStringTree
getRoot->BinaryStringTree
setParent(_:BinaryStringTree)->Void
==(_:BinaryStringTree)->Boolean}
// Constructs empty tree
// @post @return empty node
method new->BinaryStringTree is public{EmptyTree}
//Constructs tree with no children
// @post @return tree with value str and 2 empty subtrees
// @param str: a non-empty string
method withValue(str:String)->BinaryStringTree is public{
var tr:BinaryStringTree := BinaryTree.new(str, EmptyTree, EmptyTree)
tr.setLeft(EmptyTree)
tr.setRight(EmptyTree)
return tr}
//Constructs tree with two children
// @post @return tree with value str and two subtrees
// @param str: a non-empty string
// @param lt, rt: left and right subtrees
method withValue(str:String)left(lt:BinaryStringTree)
right(rt:BinaryStringTree)->BinaryStringTree is public{
var tr:BinaryStringTree := BinaryTree.new(str, lt, rt)
tr.setLeft(lt)
tr.setRight(rt)
return tr}
// Instance of empty tree
def EmptyTree:BinaryStringTree is public, readable = object{
var value:String is readable:= ""
var parent:BinaryStringTree is readable := self
var left:BinaryStringTree is readable := self
var right:BinaryStringTree is readable := self
method setLeft(_:BinaryStringTree)->Void is public{
print "can't set left of empty tree"}
method setRight(_:BinaryStringTree)->Void is public{
print "can't set right of empty tree"}
method clear->Void is public{return Void}
method isEmpty->Boolean is public{true}
method isLeaf->Boolean is public{false}
method isLeftChild->Boolean is public{false}
method isRightChild->Boolean is public{false}
method isRoot->Boolean is public{false}
method height->Number is public{-1}
method depth->Number is public{0}
method getString->String is public{value}
method getLeftChild->BinaryStringTree is public{left}
method getRightChild->BinaryStringTree is public{right}
method getParent->BinaryStringTree is public{parent}
method getRoot->BinaryStringTree is public{self}
method setParent(_:BinaryStringTree)->Void is public{return Void}
method ==(bt:BinaryStringTree)->Boolean is public{bt.isEmpty}
}
class BinaryTree.new(str:String, lt:BinaryStringTree, rt:BinaryStringTree){
var value:String is readable := str
var parent:BinaryStringTree is readable := EmptyTree
var left:BinaryStringTree is readable := EmptyTree
var right:BinaryStringTree is readable := EmptyTree
// @post sets left subtree to newLeft, reparents newLeft if not empty
// @param newLeft the root of the new left subtree
method setLeft(newLeft:BinaryStringTree)->Void is public{
left := newLeft
if(!newLeft.isEmpty) then {left.setParent(self)}
}
// @post sets right subtree to newRight, reparents newRight if not empty
// @param newRight the root of the new right subtree
method setRight(newRight:BinaryStringTree)->Void is public{
right := newRight
if(!newRight.isEmpty) then {right.setParent(self)}
}
// @post replaces tree with an empty one
method clear->Void is public{
if(isLeftChild) then{parent.setLeft(EmptyTree)}
else{if(isRightChild) then{parent.setRight(EmptyTree)}}
value := ""
left := EmptyTree
right := EmptyTree
parent := EmptyTree}
// @post @return true iff node is empty
method isEmpty->Boolean is public{false}
// @post @return true iff node is a leaf (has parent but no children)
method isLeaf->Boolean is public{!parent.isEmpty && left.isEmpty && right.isEmpty}
// @post @return true iff node is a left child
method isLeftChild->Boolean is public{!parent.isEmpty && (self == parent.getLeftChild)}
// @post @return true iff node is a right child
method isRightChild->Boolean is public{!parent.isEmpty && (self == parent.getRightChild)}
// @post @return true iff node is root of tree
method isRoot->Boolean is public{!isEmpty && parent.isEmpty}
// @post @return maximum path length from this node to a leaf
method height->Number is public{
var max:Number :=
if(left.height > right.height) then{left.height}
else{right.height}
return 1 + max}
// @post @return path length from this node to root
method depth->Number is public{
if(parent.isEmpty) then {0}
else{1 + parent.depth}
}
// @post @return string value of node
method getString->String is public{value}
// @post @return left child of node
method getLeftChild->BinaryStringTree is public{left}
// @post @return right child of node
method getRightChild->BinaryStringTree is public{right}
// @post @return parent of node
method getParent->BinaryStringTree is public{parent}
// @post @return the root of the tree
method getRoot->BinaryStringTree is public{
var finger:BinaryStringTree := self
while{!finger.isRoot} do {finger := finger.getParent}
return finger}
// @post reparents node to parent reference
// @param newParent a reference to the new parent of this node
method setParent(newParent:BinaryStringTree)->Void is public{
parent := newParent}
// @post @return true iff the two trees have same value and subtrees
method ==(bt:BinaryStringTree)->Boolean is public{
(value == bt.getString) && (left == bt.getLeftChild) && (right == bt.getRightChild)}
}