Solution (source code)

= Solution

Return the new root of the affected <subtree>, assigning that result back to the parent's child reference:
``
def addToTree(word: String, t: Tree): Tree = {
  require(word != null)
  if (t == null) new Tree(word, 1)
  else {
    val c = word.compareTo(t.word)
    if (c < 0) t.left = addToTree(word, t.left)
    else if (c > 0) t.right = addToTree(word, t.right)
    else {
      require(t.count < Int.MaxValue)
      t.count += 1
    }
    t
  }
}
// Updating the whole structure uses: root = addToTree(word, root)
``
Assume the input <binary search tree> satisfies part (b)'s <representation invariant> and, if the key already occurs, its count can be incremented. <Structural induction> proves the <postcondition>. For an empty <subtree>, the fresh entry represents one occurrence. Otherwise the word comparison identifies the only possible child <subtree> containing the word. The <recursive call> adds exactly one occurrence there, preserving the inherited strict bounds; in the equal case only the count changes. The number of entries in the current <subtree> strictly decreases in each <recursive call>, proving <algorithm termination>. \b[The returned <binary search tree> represents the old <multiset> plus one occurrence of `word`.] With height $h$, at most $h+1$ comparisons are made; without balancing this can be linear in the number of words. Actual comparison work also depends on the compared <string data type> lengths.