两数交换---方法总结

中间变量法(最常用,但也是最安全的,在两数交换的时候,最好还是用第三方交换,以免出现不必要的错误。 )
t=i;
i=j;
j=t;

程序一:

   1: void swap(int *a, int *b)
   2: {
   3:     int temp = *a;
   4:     *a = *b;
   5:     *b = temp;     
   6: }

  然而面试官们常常并不满意这样的实现,他们很有可能要求我们不能使用其它内存,

那么又有了下面的实现方法。


加减交换法(可能会溢出,比较糟糕的做法)
i+=j;
j=i-j;
i-=j;

乘除交换方(更容易溢出,更……唉……只要知道有这么个做法就行了……)
i*=j;
j=i/j;
i/=j;

异或交换法(速度还行,只能对int,char..)
i^=j;
j^=i;
i^=j;
或者i^=j^=i^=j;

程序一:

   1: void swap(int *a, int *b)
   2: {
   3:     *a = *a ^ *b;
   4:     *b = *a ^ *b;    
   5:     *a = *a ^ *b;
   6: }

 利用赋值操作符:

   1: void swap(int *a, int *b)
   2: {
   3:     *a = *a + *b - (*b = *a);
   4: }


汇编的方法
__asm
{
push i
push j
pop i
pop j
}
利用的是先入后出、后入先出的原理

2)指针操作 对指针的操作实际上进行的是整数运算。比如:两个int指针相减得到一个整数N,该整数表示两个指针变量在内存中的储存位置隔了N*sizeof(int)个字节;int指针和一个整数相加,例如“a+10”表示以a为基地址,偏移为10*sizeof(int)处的int变量。所以我们完全可以通过和算术算法类似的运算来完成指针变量值的交换,从而达到交换变量的目的。即:

int *a,*b;    
a=new int(10);        //给指针赋值
b=new int(20);        //a=0x00030828,b=0x00030840
a=(int*)(b-a);        //a=0x00000006
b=(int*)(b-int(a));   //b=0x00030828
a=(int*)(b+int(a));   //a=0x00030840

需要注意的是:最后三句话中,只有第一句是两个指针之间的计算,其他都是指针和整数的计算,否则会导致计算错误,严重导致系统出错。
通过以上运算a、b的地址就完成了交换,a指向了原先b指向的值,b指向原先a指向的值!
此算法同样没有使用第三变量就完成了值的交换,与算术算法比较它显得不好理解,但是它有它的优点即在交换很大的数据类型时,比如说自定义的大型结构或者类,它的执行速度比算术算法快。因为它交换的时地址,而变量值在内存中是没有移动过的(称为地址算法)。

原文地址:https://www.cnblogs.com/followyourdream/p/3368443.html