题目:
输入a1,a2,...,an,b1,b2,...,bn, 在O(n)的时间,O(1)的空间将这个序列顺序改为a1,b1,a2,b2,a3,b3,...,an,bn
不需要移动,通过交换完成,只需一个交换空间
例如,N=9时,第2步执行后,实际上中间位置的两边对称的4个元素基本配对,只需交换中间的两个元素即可,如下表所示。颜色表示每次要交换的元素,左边向右交换,右边向左交换。交换过程如下表所示。
|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
n+1 |
n+2 |
n+3 |
n+4 |
n+5 |
n+6 |
n+7 |
n+8 |
n+9 |
|
|
|
|
n-8 |
n-7 |
n-6 |
n-5 |
n-4 |
n-3 |
n-2 |
n-1 |
N |
2n-8 |
2n-7 |
2n-6 |
2n-5 |
2n-4 |
2n-3 |
2n-2 |
2n-1 |
2n |
交换开始位置 |
交换个数 | |
|
a1 |
a2 |
a3 |
a4 |
a5 |
a6 |
a7 |
a8 |
a9 |
b1 |
b2 |
b3 |
b4 |
b5 |
b6 |
b7 |
b8 |
b9 |
2«n+1 |
2n-1«n |
1 |
1 |
a1 |
b1 |
a3 |
a4 |
a5 |
a6 |
a7 |
a8 |
b8 |
a2 |
b2 |
b3 |
b4 |
b5 |
b6 |
b7 |
a9 |
b9 |
3«n+1 |
2n-2«n |
2 |
2 |
a1 |
B1 |
a2 |
b2 |
a5 |
a6 |
a7 |
b6 |
b7 |
a3 |
a4 |
b3 |
b4 |
b5 |
a8 |
b8 |
a9 |
b9 |
5«n+1 |
2n-4«n |
4 |
3 |
a1 |
B1 |
a2 |
b2 |
X1 |
Y1=(a6 a7 b7) |
X2 |
X3 |
Y2=(a4 b3 b4) |
X4 |
a8 |
b8 |
a9 |
b9 |
对称交换 |
|
| ||||
|
a1 |
B1 |
a2 |
b2 |
X3 |
Y2 |
X4 |
X1 |
Y1 |
X2 |
a8 |
b8 |
a9 |
b9 |
|
|
| ||||
|
a1 |
B1 |
a2 |
b2 |
X3 |
Y2 |
X1 |
X4 |
Y1 |
X2 |
a8 |
b8 |
a9 |
b9 |
|
|
| ||||
4 |
a1 |
B1 |
a2 |
b2 |
A3 |
A4 |
B3 |
B4 |
A5 |
B5 |
A6 |
A7 |
B6 |
B7 |
a8 |
b8 |
a9 |
b9 |
|
| |
5 |
a1 |
B1 |
a2 |
b2 |
A3 |
B3 |
A4 |
B4 |
A5 |
B5 |
A6 |
B6 |
A7 |
B7 |
a8 |
b8 |
a9 |
b9 |
|
|
算法思想:
以N=9为例(中间的竖表示中间位置):
a1 a2 a3 a4 a5 a6 a7 a8 a9 | b1 b2 b3 b4 b5 b6 b7 b8 b9
头尾的元素不需任何操作
1. 左边从位置left=2开始,右边从位置n+1开始,向右交换count=1个元素,即a2,b1交换
右边从位置right=2n-1开始,左边从位置n开始,向左交换count=1个元素,即b8,a9交换
序列变为:
a1 b1 a3 a4 a5 a6 a7 a8 b8 | a2 b2 b3 b4 b5 b6 b7 a9 b9
故已经成功放好位置的有(a1,b1),(a9,b9)
其中(a8,b8),(a2,b2)也配对,只需将其交换到相应的位置即可
2. 左边从位置left=3开始,右边从位置n+1开始,向右交换count=2个元素,即a3 a4 和 a2 b2交换
右边从位置right=2n-2开始,左边从位置n开始,向左交换count=2个元素,即b6 b7 和 a8 b8交换
序列变为:
a1 b1 a2 b2 a5 a6 a7 b6 b7 | a3 a4 b3 b4 b5 a8 b8 a9 b9
故又成功放好位置的有(a2,b2),(a8,b9)
3. 左边从位置left=5开始,右边从位置n开始,已不能满足交换count=4个元素的要求,故退出循环
4. 序列缩小为a5 a6 a7 b6 b7 | a3 a4 b3 b4 b5, 对序列中没有放好的数据按快处理
将序列看作:x1=(a5) y1=(a6 a7 b6) x2=(b7) | x3=(a3) y2=(a4 b3 b4) x4=(b5)
交换x1,x3;交换x2,x4;再交换中间的x1,x4;交换y1,y2;
此时序列变为S1:a3 a4 b3 b4 a5 b5 a6 a7 b6 b7
5. 若交换到左边的b有配对的a,则中间的序列S2=(a5 b6)作为新的序列;否则将S1作为新的序列;对该序列进行上述操作,直到所有元素都放到正确的位置
此例中,(a6,a7,b6,b7),(a3,a4,b3,b4)以配对,只需交换中间的两个元素即可,序列缩小a5 b5
=====================================================================
为方便比较,序列变化如下:
a1 a2 a3 a4 a5 a6 a7 a8 a9 | b1 b2 b3 b4 b5 b6 b7 b8 b9
a1 b1 a3 a4 a5 a6 a7 a8 b8 | a2 b2 b3 b4 b5 b6 b7 a9 b9
a1 b1 a2 b2 a5 a6 a7 b6 b7 | a3 a4 b3 b4 b5 a8 b8 a9 b9
a1 b1 a2 b2 a3 a4 b3 b4 a5 | b5 a6 b6 a7 b7 a8 b8 a9 b9
a1 b1 a2 b2 a3 b3 a4 b4 a5 | b5 a6 b6 a7 b7 a8 b8 a9 b9
源代码如下:








































































































































































































































































