Search code examples
c++algorithmtime-complexityin-place

move from right side to odd positions and from left side to even in-place


Given a non-empty array of items. You have to move all the items from the right side to odd positions (zero-based), and from the left side — to even positions, as follows:

raw data: 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13

result: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

What in-place algorithm exists for this with O(n) time complexity? What is its implementation?

The inverse problem is solved here (this algorithm can be essentially inverted, but it will look ugly).


Solution

  • Here is only the algorithm itself. For details, explanations, and alternative approaches see answer for the inverse problem.

    1. Initialize pointer to the pool of right-side elements to N/2.
    2. Get largest sub-array having size 3k+1
    3. Join (3k+1)/2 elements from the array's beginning and (3k+1)/2 elements from the pool of right-side elements by exchanging appropriate sub-arrays. Update pool pointer.
    4. Apply cycle leader algorithm to the parts of this sub-array, starting from positions 1, 3, 9, ... 3k-1: move element to its proper position in sub-array (elements from the left of sub-array to even positions, from the right - to odd positions), the replaced element should be also moved to its proper position, etc. until this procedure comes back to the starting position.
    5. Process the remaining parts of the array recursively, using steps 2 .. 4.

    This problem is simpler than the inverse problem, referred in OP, because here we have to reorder sub-arrays starting from the larger ones, in the same order as doing cycle leader algorithm (the inverse problem has to do it separately and in reverse order, starting from the smaller ones to obtain O(N) complexity).