Solution (source code)

= Solution

Replace the tail call by updates to local bounds and a local rank:
``
def selectIterative(k: Int, l: Int, r: Int): Int = {
  require(0 <= l && l < r && r <= a.length)
  require(0 <= k && k < r - l)
  var low = l
  var high = r
  var rank = k
  while (high - low > 1) {
    val p = partition(low, high)
    val pivotRank = p - low
    if (rank == pivotRank) return a(p)
    if (rank < pivotRank) high = p
    else {
      rank -= pivotRank + 1
      low = p + 1
    }
  }
  a(low)
}
``
The <loop invariant> says that $l\leq low<high\leq r$, $0\leq rank<high-low$, and selecting rank `rank` in the active segment yields the originally requested <order statistic>. The original segment's <multiset> is preserved, and outside it no entries change. The updates are exactly the recursive reductions proved in part (c). The <loop variant> is $high-low$; a non-returning iteration strictly decreases it. A one-entry segment has only rank zero, establishing the final return. \b[Auxiliary space is $O(1)$], rather than a potentially deep <call stack>.