Implementation of Trees
Implementation of Trees
How can we implement a tree in a Java program? As with linked lists, there are a variety of implementation techniques, using either a nested TreeNode class or a recursive definition. We will focus on the recursive version.Implementing Binary Trees
class BinaryTree {Object data;
BinaryTree left,right;
BinaryTree(){
data = null;
left = right = null;
}
BinaryTree(Object obj){
data = obj;
left = new BinaryTree();
right = new BinaryTree();
}
BinaryTree(Object obj, BinaryTree left, BinaryTree right){
data = obj;
this.left = left;
this.right = right;
}
boolean isEmpty(){
return left==null && right==null;
}
Object getData(){
return data;
}
BinaryTree getLeft(){
return left;
}
BinaryTree getRight(){
return right;
}
}
example Count the number of nodes in a given BinaryTree
int nodeCount(BinaryTree tree){
if(tree.isEmpty())
return 0;
else
return 1 + nodeCount(tree.getLeft()) + nodeCount(tree.getRight());
}
example Display the contents of a BinaryTree using an inorder traversal.
void inorderDisplay(BinaryTree tree){
if(!tree.isEmpty()){
inorderDisplay(tree.getLeft());
System.out.println(tree.getData());
inorderDisplay(tree.getRight());
}
}
Implementing Non-binary Trees
class Tree {Object root;
List children;
Tree(Object root){
this.root = root;
children = new ArrayList(); // or LinkedList
}
Tree(Object root, List children){
this.root = root;
this.children = children;
}
Object getRoot(){
return root;
}
List getChildren(){
return children;
}
}
example Count the nodes in a given tree
int nodeCount(Tree t){
int count = 1; // count the root
Iterator i = t.getChildren().iterator();
while(i.hasNext())
count += nodeCount((Tree)i.next());
return count;
}
example Display the contents of a given tree in preorder sequence
void preorderDisplay(Tree t){
System.out.println(t.getRoot().toString());
Iterator i = t.getChildren().iterator();
while(i.hasNext())
preorderDisplay((Tree)i.next());
}
example Modify the display method so that the children of a node are indented
void preorderDisplay(Tree t, int indentation){
for(int i=0;i<3*indentation;i++)
System.out.print(" ");
Iterator i = t.getChildren().iterator();
while(i.hasNext())
preorderDisplay((Tree)i.next(), indentation+1);
}
void preorderDisplay(Tree t){
preorderDisplay(t,0);
}
Tree Iterators
We can define an iterator method for a tree or binary tree. Actually, we could define four different iterators, one for each traversal ordering. Here are two for binary trees:Iterator iterator(){
class BreadthFirstIterator implements Iterator {
Queue q = new Queue();
BreadthFirstIterator(BinaryTree b){
if(!b.isEmpty())
q.enqueue(b);
}
boolean hasNext(){
return !q.isEmpty();
}
Object next() {
BinaryTree b = (BinaryTree) q.dequeue();
if(!b.left.isEmpty())
q.enqueue(b.left);
if(!b.right.isEmpty())
q.enqueue(b.right);
return b.data;
}
}
return new BreadthFirstIterator(this);
}
Iterator iterator(){
class PreorderIterator implements Iterator {
Stack s = new Stack();
PreorderIterator(BinaryTree b){
if(!b.isEmpty())
s.push(b);
}
boolean hasNext(){
return !s.isEmpty();
}
Object next() {
BinaryTree b = (BinaryTree) s.pop();
if(!b.right.isEmpty())
s.push(b.right);
if(!b.left.isEmpty())
s.push(b.left);
return b.data;
}
}
return new PreorderIterator(this);
}
Cloning a tree
java.util defines an interface called Clonable as follows:interface Clonable {
public Object clone();
}
The clone method creates and returns a copy of the object to which it is applied.
exercise Write a clone method for binary trees:
public Object clone(){
if(isEmpty())
return new BinaryTree();
else
return new BinaryTree(data, left.clone(), right.clone());
}
Q: What would happen if "left.clone()" and "right.clone()" were replaced by "left" and "right"?
Q: What would happen if "data" were replaced by "data.clone()"?