对于这个问题又两种方法
第一种通过按位异或实现
int a=7,b=5;
a=a^b;
b=a^b;
a=a^b;
最终a=7,b=5,看起来虽然奇怪,但是的确能做到交换的效果,具体过程转换成2进制来看:
a=0111;
b=0101;
a=0111^0101; / / =0010 ,一样的置0,不一样的置1
b=0010^0101; //=0111=7;
a=0010^0111; //=0101=5
交换的过程就是这样,没有什么大的道理,仔细揣摩还是有点意思。
但是用这种方法需要注意一个问题,就是不能拿相同的变量来作交换,意思就是自己不能跟自己交换。听起来会觉得很奇怪,谁没事让一个变量自己跟自己交换呢,下面我说一个我遇到的例子,就是用这种方式来交换数据,结果出bug了,调试了很久才发现的。看代码:
/**
* 交换方法
* @param arr
* @param i
* @param j
*/
public static void swap(int[] arr,int i,int j){
if(i==j){
return;
}
arr[i]=arr[i]^arr[j];
arr[j]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
}
public static int partition(int left,int right,int point){
int leftPtr=left-1;
int rightPtr=right;
while(true){
while(leftPtr<rightPtr&&arr[++leftPtr]<point);
while(leftPtr<rightPtr&&arr[--rightPtr]>point);
if(leftPtr==rightPtr){
break;
}else{
swap(arr, leftPtr, rightPtr);
}
}
swap(arr, leftPtr, right);
return leftPtr;
}
private static void segmentation(int left, int right) {
if(left>right){
return;
}
int point =arr[right];
int partition=partition(left, right, point);
segmentation(left, partition-1);
segmentation(partition+1, right);
}
这是一个快速排序的算法,没写注释,也不必看懂,就注意那个交换数据的方法,在交换之前我加了一句判断,判断给定的索引是不是相等,如果相等的话,那么arr[i]和arr[j]就是同一个东西,他们地址什么的都相同,这个时候他们再交换,结果就是他们都将会被置0,所以出现这种情况,就直接让它返回,不必再作交换,如果没这个判断,这个排序是有问题的。所以举这个例子就是为了说明bug无处不在,需处处小心。
第二种方法就是用加减法交换
int a=12;
int b=15;
a=b-a;
b=b-a;
a=b+a;
这种方法都能看懂,就不多说,这个要注意的就是数据可能会溢出,所以在使用之前要考虑数据范围。
两种方法比较起来,按位与的方式效率略微高一些。