工作好几年了,打算重新梳理一下C/C++的知识结构,所以从最基本的开始做起,以下是交换算法:
#include <iostream>
using namespace std;
template<typename T>
void swap0(T a, T b)
{
T temp = a;
a = b;
b = temp;
}
template<typename T>
void swap1(T& a, T& b)
{
T temp = a;
a = b;
b = temp;
}
template<typename T>
void swap2(T& a, T& b)
{
a = a + b;
b = a - b;
a = a - b;
}
template<typename T>
void swap3(T& a, T& b)
{
a ^= b;
b ^= a;
a ^= b;
}
int main()
{
int a = 10, b = 20;
cout << "Before using swap0(int a, int b) :" << "\t( " << a << ", " << b << " )" << endl;
swap0<int>(a, b);
cout << "Result :" << "\t( " << a << ", " << b << " )" << endl;
a = 10;
b = 20;
cout << "Before using swap1(int& a, int& b) :" << "\t( " << a << ", " << b << " )" << endl;
swap1<int>(a, b);
cout << "Result :" << "\t( " << a << ", " << b << " )" << endl;
a = 10;
b = 20;
cout << "Before using swap2(int& a, int& b) :" << "\t( " << a << ", " << b << " )" << endl;
swap2<int>(a, b);
cout << "Result :" << "\t( " << a << ", " << b << " )" << endl;
a = 10;
b = 20;
cout << "Before using swap3(int& a, int& b) :" << "\t( " << a << ", " << b << " )" << endl;
swap3<int>(a, b);
cout << "Result :" << "\t( " << a << ", " << b << " )" << endl;
return 0;
}
这里的交换算法使用了模板,是为了说明各种交换算法在一些场景中的不同之处。下面是执行结果:
Before using swap0(int a, int b) : ( 10, 20 )
Result : ( 10, 20 )
Before using swap1(int& a, int& b) : ( 10, 20 )
Result : ( 20, 10 )
Before using swap2(int& a, int& b) : ( 10, 20 )
Result : ( 20, 10 )
Before using swap3(int& a, int& b) : ( 10, 20 )
Result : ( 20, 10 )
从结果可以看出,swap0使用参数值传递,仅形参在函数体内部完成了交换,但是实参并未发生变化。
与swap0对应的swap1使用引用传递参数,即可以对实参进行直接操作,满足需求。
swap2算法使用加法做交换,算是另辟蹊径,但是有时会出现一点点小问题,比如:
char i = 98;
char j = 97;
i = i + j;
cout << "( i + j ): " << i << endl;
j = i - j;
cout << "( i - j ): " << j << endl;
i = i - j;
cout << "( i - j ): " << i << endl;
cout << "Before using swap2(T& a, T& b) :" << "\t( " << i << ", " << j << " )" << endl;
swap2<char>(i, j);
cout << "Result :" << "\t( " << i << ", " << j << " )" << endl;
输出结果为:
( i + j ): �
( i - j ): b
( i - j ): a
Before using swap2(T& a, T& b) : ( a, b )
Result : ( b, a )
可以发现该函数内部加法运算产生了溢出,尽管结果依然正确,但是需要注意这里的加法和减法运算都有溢出的风险。
最后swap3使用异或位运算完成交换,效率很高,但是也有需要注意的地方,在Linux小白一文中给出当使用异或交换算法时,需注意a==b的情况;当然了在RGBMarco的博客中给出了使用该算法交换任何类型值的具体算法,可以仔细体会一下。