通常我们的做法是(尤其是在学习阶段):定义一个新的变量,借助它完成交换。代码如下:
inta,b;
a=10; b=15;
int t;
t=a; a=b; b=t;
上面的算法最大的缺点就是需要借助一个临时变量。那么不借助临时变量可以实现交换吗?答案是肯定的!这里我们可以用三种算法来实现:1)算术运算;2)指针地址操作;3)位运算;4)栈实现。
1) 算术运算
int a,b;
a=10;b=12;
a=b-a;//a=2;b=12
b=b-a;//a=2;b=10
a=b+a;//a=10;b=10
2) 指针地址操作
因为对地址的操作实际上进行的是整数运算,比如:两个地址相减得到一个整数,表示两个变量在内存中的储存位置隔了多少个字节;地址和一个整数相加即“a+10”表示以a为基地址的在a后10个a类数据单元的地址。所以理论上可以通过和算术算法类似的运算来完成地址的交换,从而达到交换变量的目的。即:
int*a,*b;//假设*a=newint(10);*b=newint(20);//&a=0x00001000h,&b=0x00001200h
a=(int*)(b-a);//&a=0x00000200h,&b=0x00001200h
b=(int*)(b-a);//&a=0x00000200h,&b=0x00001000h
a=(int*)(b+int(a));//&a=0x00001200h,&b=0x00001000h
3) 位运算
int a=10,b=12;//a=1010^b=1100;
a=a^b;//a=0110^b=1100;
b=a^b;//a=0110^b=1010;
a=a^b;//a=1100=12;
b=1010;
^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1
此算法能够实现是由异或运算的特点决定的,通过异或运算能够使数据中的某些位翻转,其他位不变。这就意味着任意一个数与任意一个给定的值连续异或两次,值不变,(理论上重载“^”运算符,也可以实现任意结构的交换)。
4)栈实现。不多解释了,栈和相关函数定义省去
intexchange(intx,inty)
{
stack S;
push(S,x);
push(S,y);
x=pop(S);
y=pop(S);
}
以上算法均实现了不借助其他变量来完成两个变量值的交换,相比较而言算术算法和位算法计算量相当,地址算法中计算较复杂,却可以很轻松的实现大类型(比如自定义的类或结构)的交换,而前两种只能进行整形数据的交换(理论上重载“^”运算符,也可以实现任意结构的交换)。