以N=9为例(中间的竖表示中间位置):
a
1
a
2 a
3 a
4 a
5 a
6 a
7 a
8 a
9 | 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 b
1
a
3 a
4 a
5 a
6 a
7
a
8 b8 | a2 b2 b3 b4 b5 b6 b
7
a
9 b9
故已经成功放好位置的有(a1,b1),(a9,b9)
其中(a8,b8),(a2,b2)也配对,只需将其交换到相应的位置即可
2. 左边从位置left=3开始,右边从位置n+1开始,向右交换count=2个元素,即a
3
a
4 和 a2 b2交换
右边从位置right=2n-2开始,左边从位置n开始,向左交换count=2个元素,即b6 b7 和 a8 b8交换
序列变为:
a1 b
1
a
2 b
2
a
5 a
6 a
7 b6 b7 | a
3
a
4 b3 b4 b
5
a
8 b
8
a
9 b9
故又成功放好位置的有(a2,b2),(a8,b8)
3. 左边从位置left=5开始,右边从位置n开始,已不能满足交换count=4个元素的要求,故退出循环
从中间位置对称交换count=count/2=2个元素
序列变为:
a1 b
1
a
2 b
2
a
5
a
6
a
7
a
3 a
4 | b6 b7 b3 b4 b
5
a
8 b
8
a
9 b9
4.左边从位置left=5开始的size=n-left+1=5个元素循环左移x=n-left-count+1=3位
右边从位置n+1开始的size=5个元素循环右移3位
序列变为:
a1 b
1
a
2 b
2
a
3
a
4
a
5
a
6
a
7 | b3 b4 b5 b6 b
7
a
8 b
8
a
9 b9
5.至此,将原来的序列缩小为:
a
3
a
4
a
5
a
6
a
7 | b3 b4 b5 b6 b7
对该序列进行上述操作,直到所有元素都放到正确的位置
为方便比较,序列变化如下:
a
1
a
2 a
3 a
4 a
5 a
6 a
7 a
8 a
9 | b1 b2 b3 b4 b5 b6 b7 b8 b9
a1 b
1
a
3 a
4 a
5 a
6 a
7
a
8 b8 | a2 b2 b3 b4 b5 b6 b
7
a
9 b9
a1 b
1
a
2 b
2
a
5 a
6 a
7 b6 b7 | a
3
a
4 b3 b4 b
5
a
8 b
8
a
9 b9
a1 b
1
a
2 b
2
a
3
a
4
a
5
a
6
a
7 | b3 b4 b5 b6 b
7
a
8 b
8
a
9 b9
源程序如下:
/**/
/************************************************************************
* 输入a1,a2,...,an,b1,b2,...,bn
* 在O(n)的时间,O(1)的空间
* 将这个序列顺序改为a1,b1,a2,b2,a3,b3,...,an,bn
************************************************************************/
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#include
<
stdio.h
>
#include
<
string
.h
>
#include
<
CONIO.H
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#define
MAXSIZE 2*1000
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
exchangetimes
=
0
;
//
交换次数
int
movetimes
=
0
;
//
移动次数
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
交换两个数据
void
swap(
int
*
x,
int
*
y)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int t;
t=*x;
*x=*y;
*y=t;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
exchangetimes++;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
将数组中的元素循环左移x位,n为数组的元素个数
void
rotate_left(
int
a[],
int
n,
int
x)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int t;
for(int i=0;i<x;i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
t=a[0];
for(int j=0;j<n-1;j++)
a[j]=a[j+1];
a[n-1]=t;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
movetimes+=n*x;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
将数组中的元素循环右移x位,n为数组的元素个数
void
rotate_right(
int
a[],
int
n,
int
x)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int t;
for(int i=0;i<x;i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
t=a[n-1];
for(int j=n-1;j>0;j--)
a[j]=a[j-1];
a[0]=t;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
movetimes+=n*x;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
按要求交换序列(假设元素从下标1开始存放)
void
exchange(
int
a[],
int
m)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int n=m/2;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(n==1) //a1,b1 ==>不需交换
return;
else if(n==2) //a1,a2,b1,b2 ==>只需交换中间的两个数据
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
swap(a+1,a+2);
return;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int done; //已经处理的数据个数
int left; //左边开始交换的位置
int right; //右边开始交换的位置
int count; //每次交换的数据个数
int lefta; //左边未处理的a个数
int notmatch; //左边未匹配的a个数
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//初始化
done=1;
left=1; //左边从位置1开始向右交换
right=2*n-2; //右边从位置2*n-2开始向左交换
count=1; //每次交换count个数据
lefta=notmatch=n-1;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
do
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
//交换连续的count个元素
for(int j=0;j<count;j++)
swap(a+left+j,a+n+j);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//若notmatch=0,该交换不能进行,否则为重复交换
if(notmatch>0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
for(j=0;j<count;j++)
swap(a+right-j,a+n-1-j);
}
else
break;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//交换后将其调整为要求的序列
if(count>=4)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
exchange(a+left,count);
exchange(a+right-count+1,count);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//重新调整各变量
done+=count;
lefta=n-done-count;
notmatch=lefta-count;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
left=left+count;
right=right-count;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
count*=2;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(notmatch<count)
break;
}while(1);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(notmatch<count)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
count/=2;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//由中间对称交换count个数据
for(int j=0;j<count;j++)
swap(a+n-count+j,a+n+j);
int size=n-left;
//左边的数据循环左移lefta位
rotate_left(a+left,size,lefta);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//右边的数据循环右移lefta位
rotate_right(a+n,size,lefta);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int newm=2*size;
//递归调用
exchange(a+left,newm);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
显示菜单
void
show_menu()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
printf("--------------------------------------------- ");
printf("input command to test the program ");
printf(" i or I : input n to test ");
printf(" t or T : test program ");
printf(" q or Q : quit ");
printf("--------------------------------------------- ");
printf("$ input command >");
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
显示数据
void
display(
int
a[],
int
n)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
for(int i=0; i<n;i++)
printf("%3d",a[i]);
printf(" ");
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
检查交换是否正确
bool
check(
int
a[],
int
n)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int i;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(i=0;i<n-2;i+=2)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if(a[i]!=i/2+1)
return false;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(i=1;i<n-1;i+=2)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if(a[i]!=(n+i+1)/2)
return false;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return true;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
main()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int a[MAXSIZE];
int n;
char sinput[10];
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
show_menu();
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
scanf("%s",sinput);
while(stricmp(sinput,"q")!=0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if(stricmp(sinput,"i")==0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
printf(" please input n:");
scanf("%d",&n);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//假设数组的第0个元素为0,且不对其进行操作
//且假设数组中的数据为1,2,3,...,n,n+1,n+2,...,2n
for(int i=0; i<2*n;i++) //初始化
a[i]=i+1;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
display(a,2*n);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
exchangetimes=0;
movetimes=0;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//交换
exchange(a,2*n);
display(a,2*n);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
printf(" exchange times: %d ",exchangetimes);
printf(" move times: %d ",movetimes);
}
else if(stricmp(sinput,"t")==0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
int n1,n2;
printf(" please input the begin number:");
scanf("%d",&n1);
printf(" please input the end number:");
scanf("%d",&n2);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
printf(" press any key to start ... ");
getch();
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(int i=n1;i<=n2;i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
//初始化
for(int j=0; j<2*i;j++)
a[j]=j+1;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
exchangetimes=0;
movetimes=0;
exchange(a,2*i);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(check(a,2*i))
//printf(" n=%d ... ok! ",i);
printf(" n=%d ... ok! exchange times: %d move times: %d ",i,exchangetimes,movetimes);
else
printf(" n=%d ... wrong! ",i);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
printf(" ");
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//输入命令
printf("$ input command >");
scanf("%s",sinput);
}
}
为方便讨论,贴出两个运行结果的图片:
1. 输入n
![](https://p-blog.csdn.net/images/p_blog_csdn_net/livelylittlefish/111.JPG)
2. 测试从n1~n2的所有n是否能正确运行,并提供其交换次数和移动次数
![](https://p-blog.csdn.net/images/p_blog_csdn_net/livelylittlefish/112.JPG)