binary trees like a list, a (binary) tree can be empty or non-empty. in class we will explore a...

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 expected to read about alternate implementation strategies in the textbook

Post on 22-Dec-2015

225 views

Category:

Documents


0 download

TRANSCRIPT

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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.