Data Structures, Algorithms, & Applications in Java
Chapter 14, Exercise 7

The new code for the rePlay method is given below. A test program, sample input, and output are given in the files NewCompleteWinnerTree.*.
public class NewCompleteWinnerTree extends CompleteWinnerTree
{
   /** replay matches for player i, overrides CompleteWinnerTree.rePlay */
   public void rePlay(int i)
   {
      int n = player.length - 1;  // number of players
      if (i <= 0 || i > n)
         throw new IllegalArgumentException("No player " + i);
   
      int p,   // match node
          lc,  // left child of p
          rc;  // right child of p
   
      // find first match node and its children
      if (i <= lowExt)
      {// begin at lowest level
         p = (offset + i) / 2;
         lc = 2 * p - offset; // left child of p
         rc = lc + 1;
      }
      else
      {
         p = (i - lowExt + n - 1) / 2;
         if (2 * p == n - 1)
         {
            lc = tree[2 * p];
            rc = i;
         }
         else
         {
            lc = 2 * p - n + 1 + lowExt;
            rc = lc + 1;
         }
      }
   
      int newWinner = player[lc].winnerOf(player[rc]) ? lc : rc;
      if (newWinner != i && newWinner == tree[p])
         // no need to play additional matches
         return;

      tree[p] = newWinner;
   
      // play remaining matches
      p /= 2;  // move to parent
      for (; p >= 1; p /= 2)
      {
         newWinner = player[tree[2 * p]].winnerOf(
             player[tree[2 * p + 1]]) ? tree[2 * p] : tree[2 * p + 1];
         if (newWinner != i || newWinner == tree[p])
            // no need to play additional matches
            return;
         tree[p] = newWinner;
      }
   }
}