**Topic**

There is an array of length 2n {a1,a2,a3,..., an,b1,b2,b3,..., bn}, if you wish to sort {a1,b1,a2,b2,...., an,bn}, consider a solution with no time complexity O (n), spatial complexity 0 (1).

**Source**

2013 UC's School recruit Pen test

**Idea One**

Step ①, determine the position of the B1, that is, let B1 with the A2,A3,A4 in front of it exchange:

`a1，b1，a2，a3，a4，b2，b3，b4`

Step ②, then determine the position of B2, that is, let B2 with the a3,a4 in front of it exchange:

`a1，b1，a2，b2，a3，a4，b3，b4`

Step ③, B3 and the A4 in front of it swap location:

`a1，b1，a2，b2，a3，b3，a4，b4`

The B4 is in the final position and does not need to be exchanged again. So, after the 3 steps above, we get the last sequence we want. But the time complexity of this method is O (n^2)

**Code One**

`/* ---------------------------------------------* Date: 2015-02-13* sjf0115* title: Perfect Shuffle Algorithm * Source: 2013 UC's School recruit Pen question * Blog:-- ---------------------------------------------*/#include <iostream>using namespace Std; class solution { Public:voidPerfectshuffle (int*a,intN) {if(N <=1){return; }//if // intSize =2*n;int Index,Count; for(inti = N;i < Size;++i) {//Exchange number Count= N-(i-n)-1;//Pending Exchange Index= i; for(intj =1; J <=Count; ++j) {Swap (a[Index],A[I-J]);Index= I-j; }//for}//for}};intMain () {solution solution;intA[] = {1,2,3,4,5,6,7,8}; Solution. Perfectshuffle (A,4); for(inti =0; I <8; ++i) {cout<<a[i]<<" "; }//forCout<<endl;}`

**Two ideas**

Each time we let the most intermediate element in the sequence be exchanged 22. Or the above example:

`a1，a2，a3，a4，b1，b2，b3，b4`

Step ①: Exchange The most intermediate two elements a4,b1:

`a1，a2，a3，b1，a4，b2，b3，b4`

Step ②: The most intermediate two pairs of elements are exchanged individually:

`a1，a2，b1，a3，b2，a4，b3，b4`

Step ③: Exchange The most intermediate three pairs of elements:

`a1，b1，a2，b2，a3，b3，a4，b4`

This idea is the same as above, the time complexity is still O (n^2). Still but not to the topic requirement.

**Code two**

`/* ---------------------------------------------* Date: 2015-02-13* sjf0115* title: Perfect Shuffle Algorithm * Source: 2013 UC's School recruit Pen question * Blog:-- ---------------------------------------------*/#include <iostream>using namespace STD;classSolution { Public:voidPerfectshuffle (int*a,intN) {if(N <=1){return; }//if // intleft = n-1, right = N;//Exchange times for(inti =0; i < n-1; ++i) { for(intj = Left;j < right;j+=2) {Swap (a[j],a[j+1]); }//for--left; ++right; }//for}};intMain () {solution solution;intA[] = {1,2,3,4,5,6,7,8,9,Ten}; Solution. Perfectshuffle (A,5); for(inti =0; I <Ten; ++i) {cout<<A[i]<<" "; }//for cout<<endl;}`

**Idea three (perfect shuffle algorithm)**

Playing poker friends know that in a game after the shuffle, shuffle people will be accustomed to the entire set of cards broadly divided into two halves, the hands of the half to the cross shuffle.

In 2004, Microsoft's Peiyush Jain presented a perfect shuffling algorithm in his paper entitled "A simple In-place algorithm for In-shuffle".

What is the perfect shuffle problem? That is, given an array a1,a2,a3,... AN,B1,B2,B3: BN, eventually replacing it with B1,a1,b2,a2,... Bn,an. This perfect shuffle problem is essentially the same as the subject, as long as the perfect shuffle problem based on its final sequence swap 22 adjacent elements can be.

(1) The change of the original position is analyzed as follows:

(2) The change rule of each position is examined in turn:

A1:1-2

A2:2-4

A3:3-6

A4:4-8

B1:5-1

B2:6-3

B3:7-5

B4:8-7

For the element of the original array position I, the new position is **(2*i)% (2n+1)**, note that here 2n represents the length of the original array. The expression is still used later. With this expression, it is *difficult not to find the position of the element in the new array, but to "make a position" for the element*. If we use the method of temporary storage, the space complexity must reach O (N), so we need to change the idea.

(3) We think so: A1 move from position 1 to position 2, so where does the element A2 on position 2 change to? To continue this clue, we get a "closed" ring:

`1 -> 2 -> 4 -> 8 -> 7 -> 5 -> 1`

Along this ring, you can move the 6 elements of A1, A2, A4, B4, B3, and B1 to the final position, obviously, because when you move only one element at a time, the code is implemented with only 1 temporary space to complete. (ie: a=t;t=b;b=a)

In addition, another loop for this change is:

`3 -> 6 -> 3`

Along this ring, you can move the 2 elements of A3 and B2 to the final position in turn.

` //Lap algorithm voidCycleleader (int*a,intStartintN) {intPre = A[start];//2 * I% (2 * n + 1) int MoD=2* n +1;//Actual location intNext = Start *2%MoD;//Move position by ring while(Next! = start) {swap (pre,a[next]); Next =2* Next%MoD; }//whileA[start] = pre; }`

(4) The above process can be through a number of "ring" way complete element movement, is this coincidence? In fact, the research results of this issue have been published by Peiyush Jain 10 years ago in a simple in-place algorithm for In-shuffle, Microsoft, 2004. The original paper directly uses a conclusion, here is no longer proof: for **2*n = (3^k-1)** This length of the array, **just a K-ring** , and the starting position of each ring is 1,3,9, ... 3^ (k-1).

For the above example, the length is 8, which is 3^2-1, so there are only 2 rings. The starting positions of the rings are 1 and 3, respectively.

(5) At this point, the perfect Shuffle algorithm "main project" has been completed, there is only a "small" problem: If the array length is not (3^k-1) it?

If 2n!= (3^k-1), the largest integer m can always be found, making m< N, and 2m= (3^k-1).

For arrays of length 2m, the methods in the call (3) and (4) organize the elements, the remaining 2 (n-m) length, and the recursive call (5).

(6) need to swap part of an array element

(The following uses [A, a, a] to represent a sub-array from a to B, including the endpoint)

The sub-array [1,m] of the diagonal shaded portion of the ① chart should be composed of an array with [n + 1,n + m], calling the algorithm in (3) and (4);

② array [m+1,m+n] loops left n-m times. (cyclic displacement is an algorithm with a space complexity of O (1) and a time complexity of O (n).)

(7) The original problem to output a1,b1,a2,b2......an,bn, and the perfect shuffle but the output is b1,a1,b2,a2,...... Bn,an. The solution is very simple: ignore the original array of A1 and bn, for A2,a3,...... an,b1,b2,...... bn-1 call the perfect shuffle algorithm, that is, the conclusion.

As an example: n = 6

A1,a2,a3,a4,a5,a6,b1,b2,b3,b4,b5,b6

**Loop left Shift**

This paper introduces a cyclic shift operation with time complexity O (n) and a space complexity of O (1).

Ideas:

Assume that the loop moves left m bit. The array is divided into two segments, the first one is the first M element, and the second paragraph is the remaining element. Turn the first and second paragraphs upside down and turn the whole upside down.

` //Flip start position end end position voidReverse (int*a,intStartintEnd) { while(Start < end) {swap (a[start],a[end]); ++start; --end; }//while}//Loop left m bit n array length subscript starting from 1 voidLeftrotate (int*a,intMintN) {//Flip front m bitReverse (A,1, m);//Flip the remaining elementsReverse (a,m+1, n);//Overall FlipReverse (A,1, n); }`

Reference:

http://blog.csdn.net/v_july_v/article/details/10212493

Http://ask.julyedu.com/question/33

http://blog.csdn.net/caopengcs/article/details/10521603

http://cs.stackexchange.com/questions/332/in-place-algorithm-for-interleaving-an-array/400#400

[Classic face question] perfect shuffle algorithm