$\def\compare{ {\mathrm{compare}} } \def\swap{ {\mathrm{swap}} } \def\sort{ {\mathrm{sort}} } \def\true{ {\mathrm{true}} } \def\false{ {\mathrm{false}} } \def\split{ {\mathrm{split}} } \def\val{ {\mathrm{val}} } \def\lft{ {\mathrm{left}} } \def\rt{ {\mathrm{right}} } \def\size{ {\mathrm{size}} }$

Suppose $$a$$ is an array of numerical values of size $$n$$, and $$\val$$ is a numerical value. Write a method $$\split(a, \val)$$ with the following behavior:

1. $$\split$$ only modifies $$a$$ using the operation $$\swap(a, i, j)$$ that swaps the values of $$a$$ at indices $$i$$ and $$j$$,
2. after calling $$\split(a, \val)$$, there is an index $$k$$ with $$1 \leq k \leq n$$ such that for all indices $$i < k$$, $$a[i] \leq \val$$ and for all $$j \geq k$$, $$a[j] > \val$$, and
3. $$\split$$ returns the index $$k$$ as in item 2.

### Solution

Here is one (of many possible) ways of accomplishing this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Split(a, val):
left <- 1         # left index
right <- size(a)  # right index
while left < right do
if a[left] > val and a[right] <= val then
swap(a, left, right)
left <- left + 1
right <- right - 1
else
if a[left] <= val then
left <- left + 1
endif
if a[right] > val then
right <- right - 1
endif
endif
endwhile
return right + 1


To understand why this method works, we make the following observations:

1. After each iteration of the loop, we have $$a[i] \leq \val$$ for all indices $$i < \lft$$ and $$a[j] > \val$$ for all indices $$j > \rt$$.

2. In each iteration of the loop, $$\lft$$ gets increment or $$\rt$$ gets decremented (or both).

The second observation implies that the loop terminates after at most $$\size(a)$$ iterations. The first observation shows that when the loop terminates, the split is correctly performed.