CMPS 144 Spring 2019
Lab #12: Binary Search Trees and Family Trees

Activity #1: Binary Search Trees

               40 
              /  \
             /    \
            /      \
           /        \
          /          \
         /            \
        /              \
       /                \
     20                  58
    /  \                /  \
   /    \              /    \
  /      \            /      \
 /        \          /        \
4          29      47          67
 \        /  \       \        /  \
  10    25    35      52    60    73
 /  \        /
6    12    32
 \
  8
The problems associated to this activity are to be answered using pen and paper. Submit your answers to your instructor. All the problems relate to the binary search tree shown to the right.

1. Show what the tree would look like after doing each of the following operations. (Note: Each operation should be applied to the original tree shown to the right, not to the tree resulting from performing the previous operation(s).)

You need not reproduce the entire tree each time, but you should show enough surrounding context to make it clear which part of the tree was affected by the operation and what changes occurred there.

(a) Insert 44
(b) Remove 25
(c) Remove 4
(d) Remove 40

2. Below are two methods, each of which recursively traverses a binary tree and prints the values stored in the tree's nodes. For each method, show the output that it would produce when it is applied to the binary tree shown here.

(a) Show the output produced by printInOrder()

(b) Show the output produced by printPreOrder()

printInOrder()printPreOrder()
public static void printInOrder(BinTree t)
{
   if (t.isEmpty()) { }
   else {
      printInOrder(t.leftSubtree());
      System.out.print(t.getRoot() + " ");
      printInOrder(t.rightSubtree());
   }
}
public static void printPreOrder(BinTree t)
{
   if (t.isEmpty()) { }
   else {
      System.out.print(t.getRoot() + " ");
      printPreOrder(t.leftSubtree());
      printPreOrder(t.rightSubtree());
   }
}


Activity #2: Family Trees

The relevant files are these:

An instance of the FamilyForest class represents a forest of family trees. (A forest is just a collection of trees.) Among its methods, two are stubbed and are waiting for you to complete them.

The Cousins class is a Java application that constructs a family forest on the basis of the data in a file whose name is provided to it in a command-line argument (or, as jGrasp calls it, a "run argument"). Then it waits for the user to "ask" it to reveal the relationship between two specified "entities" that occur in the family forest. Entities are referred to by natural numbers. One of its methods is left for the student to complete.

The contents of the input.txt file describes the family forest (which has two trees) shown in the left half of the figure below. In the right half is a sample interaction between a user and the Cousins application, which was given the input.txt file as input:

         0                       17
         |                      /  \
         |                     /    \
         1                    18     19
        /|\                  /  \     |
       / | \                /    \    |
      /  |  \             20     21  22
     /   |   \
    /    |    \
   2     3     4
  /     /|      \
 /     / |       \
5     7  8        11
|       / \      / |\
|      /   \    /  | \
6     9    10  12 13  14
                  / \
                 /   \
                15   16
Enter pair of entity IDs: 12 4
2-descendant

Enter pair of entity IDs: 1 15
4-ancestor

Enter pair of entity IDs: 2 16
0-cousins 3 times removed

Enter pair of entity IDs: 9 15
2-cousins 1 times removed

Enter pair of entity IDs: 7 19
Unrelated

Enter pair of entity IDs: 18 18
0-ancestor

Enter pair of entity IDs: -1 5
Goodbye.

The relationship (or lack thereof) between two entities A and B falls into one of four categories:

  1. A and B are unrelated if they have no common ancestor, which is to say that they lie in distinct trees of the family forest.
  2. A is the k-ancestor of B if the path of length k from B towards the root of its tree lands at A. For example, if A is B's grandparent, then A is the 2-ancestor of B. If A and B are the same entity, A is the 0-ancestor of B.
  3. A is a k-descendant of B if the path of length k from A towards the root of its tree lands at B.
  4. A and B are k-th cousins r times removed if the nearest common ancestor of A and B, call it C, is neither A nor B, and

    where dist(x,y) is the length of the path from x to y (i.e., the number of edges in that path).