先看例子:
偶数
a[6]: 0 , 1 , 2 | 3 , 4 , 5 //MaxSize=6
则应该 i < 6/2=3; 即 0 1 2 交换 3 4 5
奇数
a[7]: 0 , 1 , 2 , 3 , 4 , 5 , 6 //MaxSize=7
则应该 i < 7/2=3.5;
a[3]———a[7-3-1] = a[3]
所以a[3]会跟自己交换一次:即 0 1 2 3 交换 3 4 5 6
正确:
int temp;
for(int i=0; i<MaxSize/2; i++){
temp = a[i];
a[i] = a[MaxSize-i-1];
a[MaxSize-i-1] = temp;
}
综上,不分奇偶,边界设为MaxSize/2即可:
for(int i = 0;i < MaxSize/2;i++)
PS:这应该作为结论记住。
若钻牛角一点,就是不想多做奇数长度中间位置的交换怎么办?
即上面提到的a[7]的a[3]跟a[3]自己交换。
① 边界分奇偶数讨论设置
int bound;
int temp;
if(MaxSize%2 == 0)
bound = MaxSize/2;
else
bound = (MaxSize-1)/2;
for(int i = 0;i < bound;i++)
{
temp = a[i];
a[i] = a[MaxSize-1-i]; //由0+5=1+4=2+3=5可以归纳出对称位置为MaxSize-1-i
a[MaxSize-1-i] = temp;
}
② 边界设为i <= MaxSize/2-1
int temp;
for(int i=0;i <= MaxSize/2-1;i++)
{
temp = a[i];
a[i] = a[MaxSize-1-i]; //由0+5=1+4=2+3=5可以归纳出对称位置为MaxSize-1-i
a[MaxSize-1-i] = temp;
}
这对于偶数长度一样是适用的:如a[6],则 i <= MaxSize/2-1 = 2,i <= 2,同样适用的。
③ 既稳妥又思路清晰的办法:左右双指针法
// 多用了一个存储空间j而已
int temp;
for(int i = 0,int j = MaxSize-1;i < j ;i++,j--) //注意,若用i <= j则奇数时多交换了一次
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
④ 还是使用i < MaxSize/2,但是在swap上做”减枝“
for(int i=0; i<MaxSize/2; i++){
swap(a,i,MaxSize-1-i);
}
public void swap(int[] nums, int i, int j){
// 进行判断,如果是自己跟自己,则不用交换
if(i != j ){
nums[i] = nums[i]^nums[j];
nums[j] = nums[i]^nums[j];
nums[i] = nums[i]^nums[j];
}
}
最后,综合来看,还是使用i < MaxSize/2比较好,多交换一个,代码简洁,记忆负担小:
for(int i=0; i<MaxSize/2; i++){
a[i] = a[i]^a[MaxSize-1-i];
a[MaxSize-1-i] = a[i]^a[MaxSize-1-i];
a[i] = a[i]^a[MaxSize-1-i];
}