Data Structures and Abstractions with Java 5 th
Data Structures and Abstractions with Java™ 5 th Edition Chapter 25 Tree Implementations Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Nodes in a Binary Tree FIGURE 25 -1 A node in a binary tree Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Binary Tree Node (Part 1) package Tree. Package; /** A class that represents nodes in a binary tree. */ class Binary. Node<T> { private T data; private Binary. Node<T> left. Child; // Reference to left child private Binary. Node<T> right. Child; // Reference to right child public Binary. Node() { this(null); // Call next constructor } // end default constructor public Binary. Node(T data. Portion) { this(data. Portion, null); // Call next constructor } // end constructor public Binary. Node(T data. Portion, Binary. Node<T> new. Left. Child, Binary. Node<T> new. Right. Child) { data = data. Portion; left. Child = new. Left. Child; right. Child = new. Right. Child; } // end constructor LISTING 25 -1 The class Binary. Node Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Binary Tree Node (Part 2) /** Retrieves the data portion of this node. @return The object in the data portion of the node. */ public T get. Data(). { return data; } // end get. Data /** Sets the data portion of this node. @param new. Data The data object. */ public void set. Data(T new. Data) { data = new. Data; } // end set. Data /** Retrieves the left child of this node. @return A reference to this node's left child. */ public Binary. Node<T> get. Left. Child() { return left. Child; } // end get. Left. Child /** Sets this node’s left child to a given node. @param new. Left. Child A node that will be the left child. */ public void set. Left. Child(Binary. Node<T> new. Left. Child) { left. Child = new. Left. Child; } // end set. Left. Child LISTING 25 -1 The class Binary. Node Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Binary Tree Node (Part 3) /** Detects whether this node has a left child. @return True if the node has a left child. */ public boolean has. Left. Child() { return left. Child != null; } // end has. Left. Child /* Implementations of get. Right. Child, set. Right. Child, and has. Right. Child are here and are analogous to their left-child counterparts. */ /** Detects whether this node is a leaf. @return True if the node is a leaf. */ public boolean is. Leaf() { return (left. Child == null) && (right. Child == null); } // end is. Leaf /** Counts the nodes in the subtree rooted at this node. @return The number of nodes in the subtree rooted at this node. */ public int get. Number. Of. Nodes() { // < Coming later —— See Segment 25. 10. > } // end get. Number. Of. Nodes LISTING 25 -1 The class Binary. Node Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Binary Tree Node (Part 4) /** Computes the height of the subtree rooted at this node. @return The height of the subtree rooted at this node. */ public int get. Height() { // < Coming later —- See Segment 25. 10. > } // end get. Height /** Copies the subtree rooted at this node. @return The root of a copy of the subtree rooted at this node. */ public Binary. Node<T> copy() { // < Coming later —— See Segment 25. 5. > } // end copy } // end Binary. Node LISTING 25 -1 The class Binary. Node Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Interface for a Basic Binary Tree package Tree. Package; /** An interface for the ADT binary tree. */ public interface Binary. Tree. Interface<T> extends Tree. Interface<T>, Tree. Iterator. Interface<T> { /** Sets the data in the root of this binary tree. @param root. Data The object that is the data for the tree's root. */ public void set. Root. Data(T root. Data); /** Sets this binary tree to a new binary tree. @param root. Data The object that is the data for the new tree's root. @param left. Tree The left subtree of the new tree. @param right. Tree The right subtree of the new tree. */ public void set. Tree(T root. Data, Binary. Tree. Interface<T> left. Tree, Binary. Tree. Interface<T> right. Tree); } // end Binary. Tree. Interface for a class of binary trees Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Creating a Basic Binary Tree (Part 1) package Tree. Package; import java. util. Iterator; import java. util. No. Such. Element. Exception; import Stack. And. Queue. Package. *; // Needed by tree iterators /** A class that implements the ADT binary tree. */ public class Binary. Tree<T> implements Binary. Tree. Interface<T> { private Binary. Node<T> root; public Binary. Tree() { root = null; } // end default constructor public Binary. Tree(T root. Data) { root = new Binary. Node<>(root. Data); } // end constructor public Binary. Tree(T root. Data, Binary. Tree<T> left. Tree, Binary. Tree<T> right. Tree) { initialize. Tree(root. Data, left. Tree, right. Tree); } // end constructor LISTING 25 -2 A first draft of the class Binary. Tree Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Creating a Basic Binary Tree (Part 2) public void set. Tree(T root. Data, Binary. Tree. Interface<T> left. Tree, Binary. Tree. Interface<T> right. Tree) { initialize. Tree(root. Data, (Binary. Tree<T>)left. Tree, (Binary. Tree<T>)right. Tree); } // end set. Tree private void initialize. Tree(T root. Data, Binary. Tree<T> left. Tree, Binary. Tree<T> right. Tree) { // < FIRST DRAFT - See Segments 25. 4 - 25. 7 for improvements. > root = new Binary. Node<T>(root. Data); if (left. Tree != null) root. set. Left. Child(left. Tree. root); if (right. Tree != null) root. set. Right. Child(right. Tree. root); } // end initialize. Tree /* Implementations of set. Root. Data, get. Height, get. Number. Of. Nodes, is. Empty, clear, and the methods specified in Tree. Iterator. Interface are here. . */ } // end Binary. Tree LISTING 25 -2 A first draft of the class Binary. Tree Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Creating a Binary Tree tree. A. set. Tree(a, tree. B, tree. C); FIGURE 25 -2 The binary tree. A shares nodes with tree. B and tree. C Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
The Method copy /** Copies the subtree rooted at this node. */ public Binary. Node<T> copy() { Binary. Node<T> new. Root = new Binary. Node<>(data); if (left. Child != null) new. Root. set. Left. Child(left. Child. copy()); if (right. Child != null) new. Root. set. Right. Child(right. Child. copy()); return new. Root; } // end copy Definition of the method copy in the class Binary. Node Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
The Method initialize. Tree private void initialize. Tree(T root. Data, Binary. Tree<T> left. Tree, Binary. Tree<T> right. Tree) { root = new Binary. Node<>(root. Data); if ((left. Tree != null) && !left. Tree. is. Empty()) root. set. Left. Child(left. Tree. root. copy()); if ((right. Tree != null) && !right. Tree. is. Empty()) root. set. Right. Child(right. Tree. root. copy()); } // end initialize. Tree Method initialize. Tree can invoke copy to copy the nodes from the two given subtrees Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Additional Challenges FIGURE 25 -3 tree. A has identical subtrees Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Method initialize. Tree Solution • If left subtree exists and not empty, ▪ attach root node to r as left child. • Create root node r containing given data. • If right subtree exists, not empty, and distinct from left subtree, – attach root node to r as a right child. • But if right and left subtrees are same, – attach copy of right subtree to r instead. • If the left subtree exists and differs from the tree object used to call initialize. Tree, – set the subtree’s data field root to null. • If right subtree exists and differs from the tree object used to call initialize. Tree, – set subtree’s data field root to null. Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Method initialize. Tree Solution private void initialize. Tree(T root. Data, Binary. Tree<T> left. Tree, Binary. Tree<T> right. Tree) { root = new Binary. Node<>(root. Data); if ((left. Tree != null) && !left. Tree. is. Empty()) root. set. Left. Child(left. Tree. root); if ((right. Tree != null) && !right. Tree. is. Empty()) { if (right. Tree != left. Tree) root. set. Right. Child(right. Tree. root); else root. set. Right. Child(right. Tree. root. copy()); } // end if if ((left. Tree != null) && (left. Tree != this)) left. Tree. clear(); if ((right. Tree != null) && (right. Tree != this)) right. Tree. clear(); } // end initialize. Tree An implementation of initialize. Tree Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Binary. Tree Accessor and Mutator Methods public void set. Root. Data(T root. Data) { root. set. Data(root. Data); } // end set. Root. Data public T get. Root. Data() { if (is. Empty()) throw new Empty. Tree. Exception(); else return root. get. Data(); } // end get. Root. Data protected void set. Root. Node(Binary. Node<T> root. Node) { root = root. Node; } // end set. Root. Node protected Binary. Node<T> get. Root. Node() { return root; } // end get. Root. Node Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
More Binary. Tree Methods public int get. Height() { int height = 0; if (root != null) height = root. get. Height(); return height; } // end get. Height public int get. Number. Of. Nodes() { int number. Of. Nodes = 0; if (root != null) number. Of. Nodes = root. get. Number. Of. Nodes(); return number. Of. Nodes; } // end get. Number. Of. Nodes Computing the Height and Counting Nodes Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Methods within Binary. Node. public int get. Height() { return get. Height(this); // Call private get. Height } // end get. Height private int get. Height(Binary. Node<T> node) { int height = 0; if (node != null) height = 1 + Math. max(get. Height(node. get. Left. Child()), get. Height(node. get. Right. Child())); return height; } Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Methods within Binary. Node public int get. Number. Of. Nodes() { int left. Number = 0; int right. Number = 0; if (left != null) left. Number = left. get. Number. Of. Nodes(); if (right != null) right. Number = right. get. Number. Of. Nodes(); return 1 + left. Number + right. Number; } // end get. Number. Of. Nodes Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Traversing a binary tree recursively public void inorder. Traverse() { inorder. Traverse(root); } // end inorder. Traverse private void inorder. Traverse(Binary. Node<T> node) { if (node != null) { inorder. Traverse(node. get. Left. Child()); System. out. println(node. get. Data()); inorder. Traverse(node. get. Right. Child()); } // end if } // end inorder. Traverse FIGURE 25 -4 A binary tree Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Non-recursive Traversal FIGURE 25 -5 Using a stack to perform an in-order traversal of a binary tree Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Non-recursive Traversal public void iterative. Inorder. Traverse() { Stack. Interface<Binary. Node<T>> node. Stack = new Linked. Stack<>(); Binary. Node<T> current. Node = root; while (!node. Stack. is. Empty() || (current. Node != null)) { // Find leftmost node with no left child while (current. Node != null) { node. Stack. push(current. Node); current. Node = current. Node. get. Left. Child(); } // end while // Visit leftmost node, then traverse its right subtree if (!node. Stack. is. Empty()) { Binary. Node<T> next. Node = node. Stack. pop(); // Assertion: next. Node != null, since node. Stack was not empty // before the pop System. out. println(next. Node. get. Data()); current. Node = next. Node. get. Right. Child(); } // end if } // end while } // end iterative. Inorder. Traverse Iterative version … Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Traversals That Use An Iterator (Part 1) private class Inorder. Iterator implements Iterator<T> { private Stack. Interface<Binary. Node<T>> node. Stack; private Binary. Node<T> current. Node; public Inorder. Iterator() { node. Stack = new Linked. Stack<>(); current. Node = root; } // end default constructor public void remove() { throw new Unsupported. Operation. Exception(); } // end remove public boolean has. Next() { return !node. Stack. is. Empty() || (current. Node != null); } // end has. Next LISTING 25 -3 The private inner class Inorder. Iterator Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Traversals That Use An Iterator (Part 2) public T next() { Binary. Node<T> next. Node = null; // Find leftmost node with no left child while (current. Node != null) { node. Stack. push(current. Node); current. Node = current. Node. get. Left. Child(); } // end while // Get leftmost node, then move to its right subtree if (!node. Stack. is. Empty()) { next. Node = node. Stack. pop(); // Assertion: next. Node != null, since node. Stack was not empty // before the pop current. Node = next. Node. get. Right. Child(); } else throw new No. Such. Element. Exception(); return next. Node. get. Data(); } // end next } // end Inorder. Iterator LISTING 25 -3 The private inner class Inorder. Iterator Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Using a Stack to Traverse a Binary Tree FIGURE 25 -6 Using a stack to traverse a binary tree in preorder and postorder Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Using a Queue for Level-Order Traversal FIGURE 25 -7 Using a queue to traverse a binary tree in level order Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Implementation of an Expression Tree package Tree. Package; /** An interface for an expression tree. */ public interface Expression. Tree. Interface extends Binary. Tree. Interface<String> { /** Computes the value of the expression in this tree. @return The value of the expression. */ public double evaluate(); } // end Expression. Tree. Interface LISTING 25 -4 An interface for an expression tree Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Implementation of an Expression Tree (Part 1) package Tree. Package; /** A class that implements an expression tree by extending Binary. Tree. */ public class Expression. Tree extends Binary. Tree<String> implements Expression. Tree. Interface { public Expression. Tree() { } // end default constructor public double evaluate() { return evaluate(get. Root. Node()); } // end evaluate private double get. Value. Of(String variable) { // Strings allow multicharacter variables double result = 0; // To be defined. return result; } // end get. Value. Of LISTING 25 -5 The class Expression. Tree Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Implementation of an Expression Tree (Part 1) private double compute(String operator, double first. Operand, double second. Operand) { double result = 0; // To be defined. return result; } // end compute private double evaluate(Binary. Node<String> root. Node) { double result; if (root. Node == null) result = 0; else if (root. Node. is. Leaf()) { String variable = root. Node. get. Data(); result = get. Value. Of(variable); } else { double first. Operand = evaluate(root. Node. get. Left. Child()); double second. Operand = evaluate(root. Node. get. Right. Child()); String operator = root. Node. get. Data(); result = compute(operator, first. Operand, second. Operand); } // end if return result; } // end evaluate } // end Expression. Tree LISTING 25 -5 The class Expression. Tree Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Representing General Trees FIGURE 25 -8 A node for a general tree Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Representing General Trees package Tree. Package; import java. util. Iterator; /** An interface for a node in a general tree. */ interface General. Node. Interface<T> { public T get. Data(); public void set. Data(T new. Data); public boolean is. Leaf(); public Iterator<General. Node. Interface<T>> get. Children. Iterator(); public void add. Child(General. Node. Interface<T> new. Child); } // end General. Node. Interface LISTING 25 -6 An interface for a node in a general tree Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
Representing General Trees FIGURE 25 -9 A general tree and two views of an equivalent binary tree Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
End Chapter 25 Copyright © 2019, 2015, 2012 Pearson Education, Inc. All Rights Reserved
- Slides: 33