![Page 1: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/1.jpg)
Binary Trees
• Like a list, a (binary) tree can be empty or non-empty.
• In class we will explore a state-based implementation, similar to the LRS
• You are expected to read about alternate implementation strategies in the textbook
![Page 2: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/2.jpg)
Method of aBinary Recursive Structure (BRS)
• method to grow tree: insertRoot
• method to shrink tree: removeRoot
• accessor/mutator pair for root: setRoot/getRoot
• accessor/mutator pair for left: setLeft/getLeft
• accessor/mutator pair for right: setRight/getRight
• visitor support: execute
![Page 3: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/3.jpg)
State transitions
• Empty NonEmpty: insertRoot on an empty tree
• NonEmpty Empty: removeRoot from a tree that is a leaf– A leaf is a tree both of whose children are
empty.
• No other state transitions can occur.
![Page 4: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/4.jpg)
Moreover…
• insertRoot throws an exception if called on a nonEmpty tree
• removeRoot throws an exception if called on a non-leaf tree
• Isn’t this very restrictive?
![Page 5: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/5.jpg)
Yes…but
• It is very restrictive, but for good reasons:– What would it mean to add a root to a tree that
already has one?– If you could remove the root from a tree with
nonEmpty children, what would become of those children?
![Page 6: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/6.jpg)
Usage of a BRS
• A BRS is not used “raw”, but is used to implement more specialized trees.
• Consider how we defined the SortedList in terms of the LRS: by composition.
• We will now explore how to define a sorted binary tree (a Binary Search Tree) by composition with a BRS.
![Page 7: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/7.jpg)
Binary Search Tree (BST)
• A binary search tree (BST) is a binary tree which maintains its elements in order.
• The BST order condition requires that, for every non-empty tree, the value at the root is greater than every value in the tree’s left subtree, and less than every value in the tree’s right subtree.
![Page 8: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/8.jpg)
Example 1Does this tree satisfy the BST order condition?
Fred
WilmaBetty
Barney Pebbles
![Page 9: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/9.jpg)
No!Barney < Betty < Pebbles > Fred < Wilma
Fred
WilmaBetty
Barney Pebbles
![Page 10: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/10.jpg)
Example 2Does this tree satisfy the BST order condition?
Fred
WilmaBetty
Barney Pebbles
![Page 11: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/11.jpg)
Yes!Barney < Betty < Fred < Pebbles < Wilma
Fred
WilmaBetty
Barney Pebbles
![Page 12: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/12.jpg)
Example 3Does this tree satisfy the BST order condition?
Fred
WilmaBetty
Barney Pebbles
![Page 13: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/13.jpg)
No!Betty > Barney < Fred < Pebbles < Wilma
Fred
WilmaBetty
Barney Pebbles
![Page 14: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/14.jpg)
Example 4…but if we swap Betty & Barney, we restore order!
Fred
Wilma
Betty
Barney
Pebbles
![Page 15: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/15.jpg)
Operations on a BST
• public BST insert(Comparable item)
• public BST remove(Comparable item)
• public boolean member(Comparable item)
• How do we support these? They don’t exist as methods on the BRS.
![Page 16: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/16.jpg)
Visitors to the rescue!
• Visitors on the BRS have the same basic structure as on the LRS: they deal with two cases:
– public Object emptyCase(BRS host, Object inp)
– public Object nonEmptyCase(BRS host, Object inp)
![Page 17: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/17.jpg)
Example: toStringVisitor
public class ToStringVisitor extends IAlgo {
public static final ToStringVisitor SINGLETON = new ToStringVisitor();
private ToStringVisitor() {}
public Object emptyCase(BRS host, Object input) {return "[]";
}
public Object nonEmptyCase(BRS host, Object input) { return "[" + host.getLeft().execute(this, null) + " " + host.getRoot().toString() + " "
+ host.getRight().execute(this, null) + "]";}
}
![Page 18: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/18.jpg)
Back to the BST
• Let’s first consider the insert operation.• We must consider two possibilities:
– the underlying BRS is empty• just insertRoot
– the underlying BRS is nonEmpty• we can’t insertRoot, because the BRS is nonEmpty• compare new item with root – determine whether
new item belongs in left or right subtree – insert recursively into correct subtree
![Page 19: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/19.jpg)
A first cut at the visitor
public class InsertVisitor extends IAlgo {
public Object emptyCase(BRS host, Object item) {return host.insertRoot(item);
}
public Object nonEmptyCase(BRS host, Object item) {if ( ((Comparable) item).compareTo(host.getRoot()) < 0 ) {
// item belongs in left subtreereturn host.getLeft().execute(this, item);
}else if ( ((Comparable) item).compareTo(host.getRoot()) > 0 ) {
// item belongs in right subtreereturn host.getRight().execute(this, item);
}else { // item is already in tree (Note UNIQUENESS ASSUMPTION)
return host;}
}}
![Page 20: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/20.jpg)
How about determining membership for an item?
• We must consider two possibilities:– the underlying BRS is empty
• just item was not found
– the underlying BRS is nonEmpty• compare new item with root – determine whether
new item has been found, or whether it would be in left or right subtree – look recursively into correct subtree
![Page 21: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/21.jpg)
A first cut at the visitor
public class MemberVisitor extends IAlgo {
public Object emptyCase(BRS host, Object item) {return new Boolean(false);
}
public Object nonEmptyCase(BRS host, Object item) {if ( ((Comparable) item).compareTo(host.getRoot()) < 0 ) {
// item belongs in left subtreereturn host.getLeft().execute(this, item);
}else if ( ((Comparable) item).compareTo(host.getRoot()) > 0 ) {
// item belongs in right subtreereturn host.getRight().execute(this, item);
}else { // item is already in tree (Note UNIQUENESS ASSUMPTION)
return new Boolean(true);}
}}
![Page 22: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/22.jpg)
Did you notice similarity?
• The structure of the insert and membership visitors was the same.
• A small number of details differed.
• Let’s unify!
![Page 23: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/23.jpg)
The find visitor
public class Find extends IAlgo {
public Object emptyCase(BRS host, Object item) {return host;
}
public Object nonEmptyCase(BRS host, Object item) {if ( ((Comparable) item).compareTo(host.getRoot()) < 0 ) {
// item belongs in left subtreereturn host.getLeft().execute(this, item);
}else if ( ((Comparable) item).compareTo(host.getRoot()) > 0 ) {
// item belongs in right subtreereturn host.getRight().execute(this, item);
}else { // item is already in tree (Note UNIQUENESS ASSUMPTION)
return host;}
}}
![Page 24: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/24.jpg)
Look at BST implementation
• insert, remove and member ALL make use of the same Find visitor:– first find the insertionPoint, – then do the right thing.
![Page 25: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/25.jpg)
The insert method
public BST insert(Comparable item) {
BRS insertPoint = (BRS) _tree.execute(new Find(), item);
only insert item into insertPoint if empty (duplicates ignored)
return this;
}
![Page 26: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/26.jpg)
The insert method
public BST insert(Comparable item) {
BRS insertPoint = (BRS) _tree.execute(new Find(), item);
insertPoint.execute(new IAlgo() {
public Object emptyCase(BRS host, Object input) {
host.insertRoot(input);
return null;
}
public Object nonEmptyCase(BRS host, Object input) {
return null;
}
}, item);
return this;
}
![Page 27: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/27.jpg)
The member method
public boolean member(Comparable item) {
BRS insertPoint = (BRS) _tree.execute(new Find(), item);
return whether insertPoint is empty or nonEmpty
}
![Page 28: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/28.jpg)
The member method
public boolean member(Comparable item) {
BRS insertPoint = (BRS) _tree.execute(new Find(), item);
return ((Boolean) insertPoint.execute(new IAlgo() {public Object emptyCase(BRS host, Object input) {
return new Boolean(false);
}
public Object nonEmptyCase(BRS host, Object input) {return new Boolean(true);
}
}, null)).booleanValue();
}
![Page 29: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/29.jpg)
The remove methodpublic BST remove(final Comparable item) {
BRS removePoint = (BRS) _tree.execute(new Find(), item);
handle removal differently in five different cases:
empty tree
non-empty tree with both children empty (leaf case)
non-empty tree with left child empty, right child non-empty
non-empty tree with left child non-empty, right child empty
non-empty tree with both children non-empty
return this;
}
![Page 30: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/30.jpg)
The remove methodpublic BST remove(final Comparable item) {
BRS removePoint = (BRS) _tree.execute(new Find(), item);
removePoint.execute(new FiveStateVisitor() {private IAlgo theRemovalVisitor = this;public Object emptyCase(BRS host, Object input) {
return host;}public Object leafCase(BRS host, Object input) {
host.removeRoot();return host;
}public Object leftNonEmptyCase(BRS host, Object input) {
host.setRoot(host.getLeft().getRoot());host.setRight(host.getLeft().getRight());host.setLeft(host.getLeft().getLeft());return host;
}public Object rightNonEmptyCase(BRS host, Object input) {
host.setRoot(host.getRight().getRoot());host.setLeft(host.getRight().getLeft());host.setRight(host.getRight().getRight());return host;
}public Object leftRightNonEmptyCase(BRS host, Object input) {
Object smallestInRight = host.getRight().execute(new IAlgo() {public Object emptyCase(BRS host, Object parent) {
Object smallest = ((BRS) parent).getRoot();((BRS) parent).execute(theRemovalVisitor, null);return smallest;
}public Object nonEmptyCase(BRS host, Object parent) {
return host.getLeft().execute(this, host);}
}, null);host.setRoot(smallestInRight);return host;
}}, item);return this;
}
![Page 31: Binary Trees Like a list, a (binary) tree can be empty or non-empty. In class we will explore a state-based implementation, similar to the LRS You are](https://reader035.vdocuments.net/reader035/viewer/2022062516/56649d7e5503460f94a60d94/html5/thumbnails/31.jpg)
Question
How do we make the 5-way distinction?
See the FiveStateVisitor definition in the lecture code repository.
Basic idea: check left, then check right.