You don't say what you want done with zeroes; this assumes zeroes are ignored and their position doesn't matter. if zeroes should be treated as positives, or negatives, or if they should appear in the middle and not in arbitrary positions, some of the details below will need to be adjusted, but this will get you basically where you want to go.
- Starting on the left, scanning right, find the first positive number. We will call its zero-based index
i
. If no positive number is found, terminate the algorithm.
- Starting on the right, scanning left, find the first negative number. We will call its zero-based index
j
. If no negative number is found, terminate the algorithm.
- Iff
i < j
, swap elements at indices i
and j
, and recursively solve the same problem for the slice of the array from i+1
to j-1
, inclusive (if i+1 >= j-1
, you may simply terminate).
This is guaranteed to solve your problem correctly. The proof is by mathematical induction on the length of the array.
Base case: empty arrays and arrays of length 1 already satisfy the desired property with no swapping required. The algorithm looks at such arrays and does nothing too them.
Induction hypothesis: assume that all arrays of up to k
elements are correctly processe by the algorithm; that is, the algorithm moves all negative elements to the left and all positive elements to the right.
Induction step: we must show that the algorithm correctly handles arrays of length k+1
. Suppose the array of k+1
elements already satisfies the property. Our algorithm looks at all elements and does nothing. Suppose instead that there is at least one element out of place. That means there is a positive number with a negative number to the right of it. In particular, there is a leftmost positive number with a negative number to the right of it. Similarly, there is a rightmost negative number with a positive number to the left of it. Our algorithm swaps these two numbers, creating an array where these numbers are no longer out of place. Since we assumed the leftmost and rightmost positive and negative numbers, any other swaps must occur inside the numbers we just swapped. Our algorithm processes this part of the array, which has size at most k+1-2 = k-1
, which, by the hypothesis, our algorithm handles correctly. QED
Pseudocode of an iterative implementation:
i = 0
j = n-1
while i < j do
while !(array[i] > 0) do
i = i + 1
while !(array[j] < 0) do
j = j - 1
if i < j then
tmp = array[i]
array[i] = array[j]
array[j] = tmp
If you want to treat zeroes as negatives, change array[j] < 0
to array[j] <= 0
. If you want to treat zeroes as positives, change array[i] > 0
to array[i] >= 0
. If you want zeroes in the middle, then run the above pseudocode three times: once to swap negatives and positives, once to swap negatives and zeros, and one to swap positives and zeroes.