CS II: Data Structures Discussion worksheet: Week 8

CS II: Data Structures
Discussion worksheet: Week 8
Trees
1) Vocabulary Answer the following question based on the above tree (Fig 8.3)
a. Which node is the root?
Sol. /user/rt/courses/
b. What are the internal nodes?
Sol. /user/rt/courses/, cs016/, cs252/, homeworks/, programs/, projects/, papers/, demos/
c. What are the leaf nodes?
Sol. grades, hw1, hw2, hw3, pr1, pr3, pr3, buylow, sellhigh, market, grades
d. How many descendants does node cs016/ have?
Sol. 9
e. How many ancestors does node cs016/ have?
Sol. 1
f.
What are the siblings of node homeworks/?
Sol. grades/, programs/
g. Which nodes are in the subtree rooted at node projects/?
Sol. papers/, demos/
h. What is the depth of node papers/?
Sol. 2
i.
What is the height of the tree?
Sol. 4
2) Finish the method sumOfLeaves, which calculates the sum of the leaf nodes' data fields. It
should not include the internal nodes in the sum. Use recursion.
/* Class containing left and right child of current
node and key value*/
class Node {
int data;
Node left, right;
public Node(int item) {
data = item;
left = right = null;
}
}
static int sumOfLeaves(Node root) {
if(root != null) {
if(root.left != null || root.right != null) {
return sumOfLeaves(root.left)
+ sumOfLeaves(root.right);
}
else {
return root.data;
}
}
else {
return 0;
}
}
3) In what order are positions visited during a (see Fig 8.6)
a. preorder traversal of the tree
b. postorder traversal of the tree
c. inorder traversal of the tree
Sol
Preorder (VLR):
-/*+313+-952+*3-746
Postorder (LRV): 31+3*95-2+/374-*6+Inorder (LVR):
3+1*3/9-5+2-3*7-4+6
4) In this problem, you will write a method for the BinaryTree class for performing an inorder
traversal of a binary tree in linear time.
// Example of Stack Push() and Pop()
public class StackDemo {
public static void main(String args[]) {
// creating stack
Stack st = new Stack();
// populating stack
st.push("Java");
st.push("Source");
st.push("code");
// removing top object
System.out.println("Removed object is: "+st.pop());
// elements after remove
System.out.println("Elements after remove: "+st);
}
}
/*
To remind you how Stack works, here is the output of the above program:
Removed object is: code
Elements after remove: [Java, Source]
*/
/* importing the necessary class */
import java.util.Stack;
/* Class containing left and right child of current
node and key value*/
class Node {
int data;
Node left, right;
public Node(int item) {
data = item;
left = right = null;
}
}
class BinaryTree {
Node root;
// non-recursive method for inorder traversal
void inorder() {
if (root == null) {
return;
}
// use stack to keep track of the Nodes you still need to visit.
// Keep in mind that the Stack starts empty
Stack<Node> stack = new Stack<Node>();
Node node = root;
//Your code here
while (node != null) {
stack.push(node);
node = node.left;
}
// traverse the tree
while (stack.size() > 0) {
// visit the top node
node = stack.pop();
System.out.print(node.data + " ");
if (node.right != null) {
node = node.right;
// the next node to be visited is the leftmost
while (node != null) {
stack.push(node);
node = node.left;
}
}
}
}
public static void main(String args[]) {
/* creating a binary tree and entering
the nodes */
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
tree.inorder();
}
}
Reflection: why did we need a data structure (like Stack) to write the non-recursive traversal but we
didn't need one for the recursive method sumOfLeaves?
5) Two ordered trees T’ and T’’ are said to be "isomorphic" if one of the following holds:
a. Both T’ and T’’ are empty
b. Both T’ and T’’ consist of a single node
c. The roots of T’ and T’’ have the same number of k >= 1 of subtrees, and the ith such
subtree of T’ is isomorphic to the ith such subtree of T’’ for i = 1,…..,k
Design an algorithm that tests whether two given ordered trees are isomorphic. What is the
running time of your algorithm?
class BinaryTree
{
Node root1, root2;
/* Given a binary tree, print its nodes in reverse level order */
boolean isIsomorphic(Node n1, Node n2)
{
// Both roots are NULL, trees isomorphic by definition
if (n1 == null && n2 == null)
return true;
// Exactly one of the n1 and n2 is NULL, trees not isomorphic
if (n1 == null || n2 == null)
return false;
if (n1.data != n2.data)
return false;
// There are two possible cases for n1 and n2 to be isomorphic
// Case 1: The subtrees rooted at these nodes have NOT been
// "Flipped".
// Both of these subtrees have to be isomorphic.
// Case 2: The subtrees rooted at these nodes have been "Flipped"
return (isIsomorphic(n1.left, n2.left) &&
isIsomorphic(n1.right, n2.right))
|| (isIsomorphic(n1.left, n2.right) &&
isIsomorphic(n1.right, n2.left));
}
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
// Let us create trees shown in above diagram
tree.root1 = new Node(1);
tree.root1.left = new Node(2);
tree.root1.right = new Node(3);
tree.root1.left.left = new Node(4);
tree.root1.left.right = new Node(5);
tree.root1.right.left = new Node(6);
tree.root1.left.right.left = new Node(7);
tree.root1.left.right.right = new Node(8);
tree.root2 = new Node(1);
tree.root2.left = new Node(3);
tree.root2.right = new Node(2);
tree.root2.right.left = new Node(4);
tree.root2.right.right = new Node(5);
tree.root2.left.right = new Node(6);
tree.root2.right.right.left = new Node(8);
tree.root2.right.right.right = new Node(7);
if (tree.isIsomorphic(tree.root1, tree.root2) == true)
System.out.println("Yes");
else
System.out.println("No");
}
}
Time complexity is O(m + n) where m and n are number of nodes in given trees
6) Give an O(n) time algorithm for printing the depths of all nodes of a tree T, where n is the
number of nodes of T.
Sol.
This can be done using a preorder traversal. When doing a "visit" in the traversal, simply store the
depth of the node’s parent incremented by 1. Now, every node will contain its depth.
Assuming depth is a variable associated with each node, we can compute node’s depth
computingDepths(v, d)
{
v.depth=d;
if ( v has no child )
return;
else
for each child v′ do
computingDepths(v′, d+1);
return;
}
To compute the depth of each node, simply call computeDepth(root, 0). This algorithm visits
each node only once and each visit takes constant time. Therefore, it’s running time is O(n)