© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Data Structures for Java Data Structures for Java
William H. Ford William H. Ford William R. Topp William R. Topp
Chapter 18 Chapter 18
Binary Search Trees Binary Search Trees
Bret Ford
© 2005, Prentice Hall
Binary Search Tree Binary Search Tree
The nodes in a binary search tree are on The nodes in a binary search tree are on unique paths from the root according to unique paths from the root according to
an ordering principle.
an ordering principle.
The left subtree of a node contains smaller The left subtree of a node contains smaller values and the right subtree contains larger values and the right subtree contains larger
values. This implies that duplicates are not values. This implies that duplicates are not
allowed.
allowed.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Binary Search Tree (continued)
Binary Search Tree (continued)
Building a Binary Search Tree Building a Binary Search Tree
Insertion strategy: Insertion strategy:
If the value of the new element is equal to the value If the value of the new element is equal to the value of the current node, perform no action.
of the current node, perform no action.
If the value of the new element is less than the value If the value of the new element is less than the value of the current node, proceed to the left subtree (left of the current node, proceed to the left subtree (left
child) of the node. If null, insert the node as a left child) of the node. If null, insert the node as a left
child of the parent.
child of the parent.
If the value of the new element is greater than the If the value of the new element is greater than the value of the current node, proceed to the right
value of the current node, proceed to the right
subtree (right child) of the node. If null, insert the subtree (right child) of the node. If null, insert the
node as a left child of the parent.
node as a left child of the parent.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Building a Binary Search Tree Building a Binary Search Tree
(continued)
(continued)
Locating an Object in a Binary Locating an Object in a Binary
Search Tree Search Tree
Search for an element the same way Search for an element the same way you inserted it.
you inserted it.
5 0
3 7 6 2 1 0 3 2
6 0 5 3
2 5 3 5
3 0 5 5
1 5
P a t h f o r l o c a t i n g 3 2 P a t h f o r l o c a t i n g 6 0
P a t h f o r d e t e r m i n i n g t h a t 1 2 i s n o t i n t h e s e a r c h t r e e
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Inorder Scan of a Binary Inorder Scan of a Binary
Search Tree Search Tree
The first value visited in the minimum The first value visited in the minimum value in the tree.
value in the tree.
The LNR inorder scan visits the nodes in The LNR inorder scan visits the nodes in ascending order.
ascending order.
The RNL inorder scan visits the nodes in The RNL inorder scan visits the nodes in descending order.
descending order.
Removing a Binary Search Tree Removing a Binary Search Tree
Node Node
Note immediately that the root node cannot Note immediately that the root node cannot be removed from the following tree since we be removed from the following tree since we
would be left with two orphaned subtrees.
would be left with two orphaned subtrees.
We need to find a replacement value for 25.
We need to find a replacement value for 25.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Removing a Binary Search Tree Removing a Binary Search Tree
Node (continued) Node (continued)
To delete a node from a binary search To delete a node from a binary search tree, you must find a replacement node, tree, you must find a replacement node,
copy its value, and then splice it out of the copy its value, and then splice it out of the
tree.
tree.
The STree Class The STree Class
The STree class implements the The STree class implements the Collection interface.
Collection interface.
The add() method inserts a new element if a The add() method inserts a new element if a duplicate value is not already present. The duplicate value is not already present. The
boolean return value indicates whether the item boolean return value indicates whether the item
was added to the tree.
was added to the tree.
The method toArray() returns an Object array The method toArray() returns an Object array
that mirrors the inorder scan and so the elements that mirrors the inorder scan and so the elements
are referenced in ascending order. An Iterator are referenced in ascending order. An Iterator object scans the elements in ascending order.
object scans the elements in ascending order.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
The STree Class (continued) The STree Class (continued)
The constructor that creates an empty tree with The constructor that creates an empty tree with size zero.
size zero.
toString() returns a string that describes the toString() returns a string that describes the
elements in a comma separated list enclosed in elements in a comma separated list enclosed in
square brackets. The elements are listed in square brackets. The elements are listed in
ascending order.
ascending order.
The methods displayTree(), drawTree() and The methods displayTree(), drawTree() and
drawTrees() give a "tree-view" of the elements.
drawTrees() give a "tree-view" of the elements.
Methods first() and last() return the smallest and Methods first() and last() return the smallest and largest values in the tree.
largest values in the tree.
The STree Class (continued) The STree Class (continued)
The method find() takes item as an The method find() takes item as an
argument and searches the tree looking for argument and searches the tree looking for
an element whose value matches item. The an element whose value matches item. The
return value is a reference to the value field return value is a reference to the value field
of the node or null if no match occurs. The of the node or null if no match occurs. The
find() method allows an applications find() method allows an applications
programmer to update an element in the programmer to update an element in the
tree without having to remove it and tree without having to remove it and
reinsert it back in the tree. Use it to change reinsert it back in the tree. Use it to change
a field not related to the key used for a field not related to the key used for
ordering.
ordering.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
STree Class UML
STree Class UML
Program 18.1 Program 18.1
The program is a GUI application that The program is a GUI application that allows a user to dynamically update a allows a user to dynamically update a
search tree by inserting and deleting search tree by inserting and deleting
elements.
elements.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Program 18.1 (continued) Program 18.1 (continued)
public void actionPerformed(ActionEvent ae) {
// ae.getSource() is a reference to the object // that caused the ActionEvent
JButton buttonPressed = (JButton)ae.getSource();
int n;
// convert the string in input to an int n = Integer.parseInt(itemField.getText());
if (n < 0 || n > 99) {
JOptionPane.showMessageDialog(
appFrame, "Integer must be in range " + "from 0 to 99",
"Data Error", JOptionPane.ERROR_MESSAGE);
return;
}
Program 18.1 (concluded) Program 18.1 (concluded)
if (buttonPressed == addButton) tree.add(n);
else
tree.remove(n);
// display the tree in the text area
currTreeDisplay += "\n\n" + tree.displayTree(2);
textArea.setText(currTreeDisplay);
itemField.setText("");
itemField.requestFocus(true);
}
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Implementing the STree Class Implementing the STree Class
For the STree class, extend the structure For the STree class, extend the structure of a tree node to include a fourth variable of a tree node to include a fourth variable
that provides a link to the parent of the that provides a link to the parent of the
node. The STNode class defines the node. The STNode class defines the
modified tree node object.
modified tree node object.
Implementing the STree Class Implementing the STree Class
(continued) (continued)
The parent reference in STNode allows the The parent reference in STNode allows the implementation of an inorder tree iterator.
implementation of an inorder tree iterator.
The STNode class is defined as a private inner The STNode class is defined as a private inner
class in the STree class. The arrow from the class class in the STree class. The arrow from the class
to itself indicates that an STNode references other to itself indicates that an STNode references other
STNodes.
STNodes.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Implementing the STree Class Implementing the STree Class
(continued) (continued)
The example gives a tree view and a node The example gives a tree view and a node view of an STree object. Dotted lines
view of an STree object. Dotted lines
represent the parent links. Note that the represent the parent links. Note that the
parent of the root node is null.
parent of the root node is null.
STree Class Private Members STree Class Private Members
and Constructor and Constructor
Private methods findNode() and Private methods findNode() and removeNode promote code reuse.
removeNode promote code reuse.
public class STree<T> implements Collection<T>, Iterable<T>
{
// reference to tree root private STNode<T> root;
// number of elements in the tree private int treeSize;
// increases whenever the tree changes; used // by an iterator to verify that it is in a // consistent state
private int modCount;
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
STree Class Private Members STree Class Private Members
and Constructor (continued) and Constructor (continued)
// create an instance representing an empty // tree; the root is null and the variables // treeSize and modCount are initially 0 public STree()
{
root = null;
modCount = 0;
treeSize = 0;
}
STree Class Private Members STree Class Private Members
and Constructor (concluded) and Constructor (concluded)
// iteratively traverse a path from the root to
// the node whose value is item; return a reference // to the node containing item or null if the search // fails
private STNode<T> findNode(Object item) { . . . }
// private method used by remove() and the iterator // remove() to delete a node
private void removeNode(STNode<T> dNode) { . . . }
}
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Inserting and Locating a Node Inserting and Locating a Node
Method add() iteratively moves on a path Method add() iteratively moves on a path from the root until it locates an empty
from the root until it locates an empty subtree. It inserts the new node and subtree. It inserts the new node and
returns true. If it finds a duplicate, it returns true. If it finds a duplicate, it
returns false.
returns false.
STree Method add() STree Method add()
// if item is not in the tree, insert it and // return true; if item is a duplicate, do not // insert it and return false
public boolean add(T item) {
// t is current node in traversal, parent the // previous node
STNode<T> t = root, parent = null, newNode;
int orderValue = 0;
// terminate on an empty subtree while(t != null)
{
// update the parent reference parent = t;
// compare item and the current node value orderValue = ((Comparable<T>)item).compareTo(
t.nodeValue);
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
STree Method add() STree Method add()
(continued) (continued)
// if a match occurs, return false;
// otherwise, go left or go right // following search tree order if (orderValue == 0)
return false; // exit, item not added else if (orderValue < 0)
t = t.left;
else
t = t.right;
}
// create the new node
newNode = new STNode<T>(item,parent);
STree Method add() STree Method add()
(concluded) (concluded)
if (parent == null)
// this is the first node added; make it root root = newNode;
else if (orderValue < 0)
// attach newNode as the left child of parent parent.left = newNode;
else
// attach newNode as the right child of parent parent.right = newNode;
// increment the tree size and modCount treeSize++;
modCount++;
// we added a node to the tree return true;
}
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
STree Method find() STree Method find()
// search for item in the tree and return a // reference to its value or null if item // is not in the tree
public T find(T item) {
STNode<T> t = findNode(item);
T value = null;
if (t != null)
value = t.nodeValue;
return value;
}
find() uses findNode() to seek a find() uses findNode() to seek a
reference to a node containing value item.
reference to a node containing value item.
find() returns null or a reference only to find() returns null or a reference only to
the nodeValue component.
the nodeValue component.
Deleting a Node Deleting a Node
The private method removeNode() The private method removeNode()
erases a node from the tree by finding a erases a node from the tree by finding a
replacement node somewhere else in the tree replacement node somewhere else in the tree
and using it as a substitute for the deleted node.
and using it as a substitute for the deleted node.
Choose the node so that, when it takes the place of Choose the node so that, when it takes the place of the deleted node, its value maintains the structure of the deleted node, its value maintains the structure of
the tree.
the tree.
Subtrees for the deleted node and the replacement Subtrees for the deleted node and the replacement node must be reconnected in such a way that the node must be reconnected in such a way that the
new tree maintains search tree ordering.
new tree maintains search tree ordering.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Deleting a Node (continued) Deleting a Node (continued)
Notation: Notation:
dNode identifies the deleted node D. pNode, dNode identifies the deleted node D. pNode, identifies the parent P of the deleted node.
identifies the parent P of the deleted node.
When pNode is null, we are deleting the root.
When pNode is null, we are deleting the root.
The removeNode() method sets out to find a The removeNode() method sets out to find a
replacement node R with reference rNode.
replacement node R with reference rNode.
Deleting a Node (continued) Deleting a Node (continued)
The algorithm for finding a replacement The algorithm for finding a replacement node considers two cases that depend on node considers two cases that depend on
the number of children attached to node
the number of children attached to node
D. D.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Deleted Node has an Empty Deleted Node has an Empty
Subtree Subtree
The other child becomes the replacement The other child becomes the replacement node R. If the deleted node is a leaf
node R. If the deleted node is a leaf node, it has two null children. In this node, it has two null children. In this
case, the other node R is null.
case, the other node R is null.
Deleted Node has an Empty Deleted Node has an Empty
Subtree (continued)
Subtree (continued)
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Deleted Node has an Empty Deleted Node has an Empty
Subtree (continued)
Subtree (continued)
Deleted Node has an Empty Deleted Node has an Empty
Subtree (continued) Subtree (continued)
The algorithm must handle two special The algorithm must handle two special
cases, one in which the deleted node is a cases, one in which the deleted node is a
leaf node and the other in which the leaf node and the other in which the
deleted node is the root.
deleted node is the root.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Deleted Node has an Empty Deleted Node has an Empty
Subtree (continued)
Subtree (continued)
removeNode() removeNode() (one null child) (one null child)
private void removeNode(STNode<T> dNode) {
if (dNode == null) return;
// dNode = reference to node D that is deleted // pNode = reference to parent P of node D
// rNode = reference to node R that replaces D STNode<T> pNode, rNode;
// assign pNode as a reference to P pNode = dNode.parent;
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
removeNode() removeNode()
(one null child continued) (one null child continued)
// if D has a null child, the
// replacement node is the other child
if (dNode.left == null || dNode.right == null) {
if (dNode.right == null) rNode = dNode.left;
else
rNode = dNode.right;
if (rNode != null)
// the parent of R is now the parent of D rNode.parent = pNode;
removeNode() removeNode()
(one null child concluded) (one null child concluded)
// deleting the root node; assign new root if (pNode == null)
root = rNode;
// attach R to the correct branch of P
else if (((Comparable<T>)dNode.nodeValue).
compareTo(pNode.nodeValue) < 0) pNode.left = rNode;
else
pNode.right = rNode;
} ...
}
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Deleted Node has Two Nonnull Deleted Node has Two Nonnull
Children Children
A node with two children has some A node with two children has some
elements in its subtrees that are less than elements in its subtrees that are less than
and some elements that are greater than and some elements that are greater than
its value.
its value.
Find a replacement node that maintains the Find a replacement node that maintains the correct ordering among the items. Rather correct ordering among the items. Rather
than removing the deleted node, update its than removing the deleted node, update its
value with that of the replacement node.
value with that of the replacement node.
Splice the replacement node out of the tree.
Splice the replacement node out of the tree.
Deleted Node has Two Nonnull Deleted Node has Two Nonnull
Children (continued)
Children (continued)
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Deleted Node has Two Nonnull Deleted Node has Two Nonnull
Children (continued) Children (continued)
Select R as the node with the smallest Select R as the node with the smallest
value that is greater than the value of the value that is greater than the value of the
deleted node. R is the leftmost node in the deleted node. R is the leftmost node in the
right subtree of D.
right subtree of D.
Deleted Node has Two Nonnull Deleted Node has Two Nonnull
Children (continued) Children (continued)
Move to the right child of D and then far- Move to the right child of D and then far- left to the replacement node R,
left to the replacement node R,
maintaining a reference, PofR, to the maintaining a reference, PofR, to the
parent of R.
parent of R.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Deleted Node has Two Nonnull Deleted Node has Two Nonnull
Children (continued) Children (continued)
Splice out R from the tree, by copying its Splice out R from the tree, by copying its value in place of the the value of D and value in place of the the value of D and
connect its right subtree to its parent.
connect its right subtree to its parent.
removeNode() removeNode()
(two nonnull children) (two nonnull children)
public void removeNode(STNode<T> dNode) {
if (dNode.left == null || dNode.right == null) {
. . . }
// case where deleted node has two nonnull children else
{
// pOfRNode is reference to parent of // replacement node
STNode<T> pOfRNode = dNode;
// first possible replacement is right // child of D; the reference to PofR, // pOfRNode, is the deleted node
rNode = dNode.right;
pOfRNode = dNode;
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
removeNode() (two nonnull removeNode() (two nonnull
children continued) children continued)
// descend down path of left children, keeping // a record of the current node and its parent;
// stop at the replacement node while(rNode.left != null)
{
pOfRNode = rNode;
rNode = rNode.left;
}
. . . }
}
removeNode() (two nonnull removeNode() (two nonnull
children continued) children continued)
Complete the process by copying the value Complete the process by copying the value of the replacement node to D and then
of the replacement node to D and then
connect the right subtree of R to the tree.
connect the right subtree of R to the tree.
If PofR is the deleted node, then connect If PofR is the deleted node, then connect the right subtree of R as the rightchild of the right subtree of R as the rightchild of D; otherwise connect the right child of R D; otherwise connect the right child of R
as the left child of PofR. Assign the parent as the left child of PofR. Assign the parent
of a nonnull right subtree of R to be of a nonnull right subtree of R to be
pOfRNode, the parent of R.
pOfRNode, the parent of R.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
removeNode() (two nonnull removeNode() (two nonnull
children concluded) children concluded)
// copy the value in R to D
dNode.nodeValue = rNode.nodeValue;
if (pOfRNode == dNode)
dNode.right = rNode.right;
else
pOfRNode.left = rNode.right;
// the parent of the right child of R is the parent of R if (rNode.right != null)
rNode.right.parent = pOfRNode;
The method remove() The method remove()
// if item is in the tree, remove it // and return true; otherwise, return // false
public boolean remove(Object item) {
// search tree for item
STNode<T> dNode = findNode(item);
if (dNode == null) return false;
removeNode(dNode);
treeSize--;
modCount++;
return true;
}
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Additional STree Operations Additional STree Operations
The method first() must return the The method first() must return the
smallest element in the tree. In a binary smallest element in the tree. In a binary
search tree, this element is in the leftmost search tree, this element is in the leftmost
node from root.
node from root.
Additional STree Operations Additional STree Operations
(continued) (continued)
// returns the first (least) element in this // binary search tree
public T first() {
STNode<T> nextNode = root;
// if the set is empty, return null if (nextNode == null)
return null;
// first node is the furthest node left from root while (nextNode.left != null)
nextNode = nextNode.left;
return nextNode.nodeValue;
}
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Additional STree Operations Additional STree Operations
(concluded) (concluded)
The method last() must return the largest The method last() must return the largest element in the tree. In a binary search
element in the tree. In a binary search
tree, this element is in the right-most node tree, this element is in the right-most node
from root. Implement the methods by from root. Implement the methods by starting at the root and scan down the starting at the root and scan down the
path of right children. The value of the path of right children. The value of the
last node on the path is the maximum last node on the path is the maximum
value in the binary search tree.
value in the binary search tree.
Complexity of Binary Search Complexity of Binary Search
Tree Operations Tree Operations
A binary search tree has best-case search A binary search tree has best-case search time O(log
time O(log
22n), worst-case time O(n), and n), worst-case time O(n), and average time O(log
average time O(log
22n). n).
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
The STree Iterator The STree Iterator
Implement an iterative traversal of Implement an iterative traversal of
the elements using the STNode parent the elements using the STNode parent field. The figure illustrates the order of field. The figure illustrates the order of
scan for the twenty elements in the search scan for the twenty elements in the search tree. If the current iterator position is node tree. If the current iterator position is node
18, the next two elements are found by 18, the next two elements are found by
moving up to the parent 20 and then down moving up to the parent 20 and then down
the right subtree to node 22 and node 23.
the right subtree to node 22 and node 23.
From node 23 the next element is the root From node 23 the next element is the root
node 25. We locate the value by scanning node 25. We locate the value by scanning
up the path of parents four levels.
up the path of parents four levels.
The STree Iterator (continued)
The STree Iterator (continued)
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
IteratorImpl Inner Class IteratorImpl Inner Class
private class IteratorImpl implements Iterator<T>
{
// set expectedModCount to the number of list // changes at the time of iterator creation private int expectedModCount = modCount;
// node of the last value returned by next() // if that value was deleted by the iterator // method remove()
private STNode<T> lastReturned = null;
// node whose value is returned a subsequent // call to next()
private STNode<T> nextNode = null;
...
}
IteratorImpl Inner Class IteratorImpl Inner Class
(continued) (continued)
The first node is the one far-left from the root. The first node is the one far-left from the root.
Subsequent nodes are visited in LNR order.
Subsequent nodes are visited in LNR order.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
IteratorImpl Inner Class IteratorImpl Inner Class
(continued) (continued)
// constructor IteratorImpl() {
nextNode = root;
// if the tree is not empty, the first node // inorder is the farthest node left from root if (nextNode != null)
while (nextNode.left != null) nextNode = nextNode.left;
}
STree Method iterator() STree Method iterator()
// returns an iterator for the elements in the tree public Iterator<T> iterator()
{
return new IteratorImpl();
}
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Implementing next() Implementing next()
If the right subtree is not empty, obtain the If the right subtree is not empty, obtain the next node in order by moving to the right next node in order by moving to the right
child and then moving left until child and then moving left until
encountering a null subtree.
encountering a null subtree.
If the right subtree is empty, obtain the If the right subtree is empty, obtain the next node in order by following a chain of next node in order by following a chain of
parent references until locating a parent, P, parent references until locating a parent, P,
for which the current node, nodePtr, is a for which the current node, nodePtr, is a
left child. Node P is the next node in order.
left child. Node P is the next node in order.
Implementing next() Implementing next()
(continued) (continued)
When invoking next() from the node with When invoking next() from the node with the tree's maximum value, the right
the tree's maximum value, the right
subtree is empty. As we move up the tree, subtree is empty. As we move up the tree,
we are always a right child of our parent we are always a right child of our parent
until we encounter the root node, whose until we encounter the root node, whose
parent is null. In this situation, the parent is null. In this situation, the
variable nextNode becomes null and we variable nextNode becomes null and we
have completed an iteration.
have completed an iteration.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Implementing next()
Implementing next() (continued) (continued)
// returns the next element in the iteration;
// throws NoSuchElementException if iteration // has no more elements
public T next() {
// check that the iterator is in a consistent // state; throws ConcurrentModificationException // if it is not
checkIteratorState();
// check if the iteration has another element;
// if not, throw NoSuchElementException if (nextNode == null)
throw new NoSuchElementException(
"Iteration has no more elements");
// save current value of next in lastReturned lastReturned = nextNode;
// set nextNode to the next node in order STNode<T> p;
Implementing next() Implementing next()
(continued) (continued)
if (nextNode.right != null) {
// successor is the furthest left node of // right subtree
nextNode = nextNode.right;
while (nextNode.left != null) nextNode = nextNode.left;
} else {
// have already processed the left subtree, // and there is no right subtree; move up // the tree, looking for a parent for
// which nextNode is a left child, stopping // if the parent becomes null; a non-null
// parent is the successor; if parent is null, // the original node was the last node inorder p = nextNode.parent;
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Implementing next() Implementing next()
(concluded) (concluded)
while (p != null && nextNode == p.right) {
nextNode = p;
p = p.parent;
}
// if we were previously at the right-most // node in the tree, nextNode = null
nextNode = p;
}
return lastReturned.nodeValue;
}
Implementing hasNext() Implementing hasNext()
// returns true if the tree has more // unvisited elements
public boolean hasNext() {
// elements remain if nextNode is not null return nextNode != null;
}