- Get largest sub-array having size 3k+1
- 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 (even-indexed elements to the left of sub-array, odd-indexed - to the right), the replaced element should be also moved to its proper position, etc. until this procedure comes back to the starting position. This paper gives number-theoretic explanation why such selection of starting positions shuffles sub-array to the correct order.
- Process the remaining parts of the array recursively, using steps 1 and 2.
- Now we only need to join the reordered parts together. Start with the smaller sub-arrays at the end of the whole array. To exchange sub-array halves, use reverse algorithm: reverse(reverse(a), reverse(b)); or, for sub-array halves of equal size, use pair-wise swaps.
- Now all even-positioned elements are on the left. To get them on the right, as required, exchange elements i and i+N/2 for all i = 0 .. N/2-1.
Algorithm is in-place, time complexity is O(N).
Example:
0 1 2 3 4 5 6 7 8 9 10 11 (the original array)
0 1 2 3 4 5 6 7 8 9 # 10 11 (split to sub-arrays)
0 2 4 3 8 1 6 5 7 9 # 10 11 (first cycle leader iteration, starting with 1)
0 2 4 6 8 1 3 5 7 9 # 10 11 (second cycle leader iteration, starting with 3)
0 2 4 6 8 9 7 5 3 1 # 10 11(2nd half of 1st part& 1st half of 2nd part reversed)
0 2 4 6 8 10 1 3 5 7 9 11 (both halves reversed together)
Variation of this algorithm, that does not need step 5:
- On step 1, get largest sub-array having size 3k-1.
- On step 2, move even-indexed elements to the right of sub-array, odd-indexed - to the left. Use starting positions 0, 2, 8, ... 3k-1-1 for cycle-leader algorithm.
Here is different O(N log N) in-place algorithm, which does not need number-theoretic proofs:
- Reinterpret your array as a sequence of single-element 2*2 matrices, transpose these matrices.
- Reinterpret the result as a sequence of two-element 2*2 matrices and transpose them.
- Continue while matrices size is less than the array size.
- Now we only need to join the reordered parts together (exactly as in previous algorithm).
- Exchange elements of left and right halves of the array (exactly as in previous algorithm).
Example:
0 1 2 3 4 5 6 7 (the original array)
[0 2] [1 3] [4 6] [5 7] (first transposition)
[0 2] [4 6] [1 3] [5 7] (second transposition)
This problem is just a special case of the In-place matrix transposition.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…