冒泡排序
代码
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<vector>
using namespace std;
void Swap(vector<int>& arr, int i, int j)
{
// 注:^表示按位异或
arr[i] = arr[i] ^ arr[j]; // 此处得到的arr[i]表示原arr[i]和arr[j]中各位上(二进制)不同的位置
arr[j] = arr[i] ^ arr[j];
// 解释,理论推导在最下面:
// Ⅰ.若在某一位上的新arr[i]为1,那么说明原arr[i]和arr[j]在当前位不同,此时有
// 1)若当前位原arr[j]为1,那么输出新arr[j]为0,且说明原arr[i]在当前位为0;
// 2)若当前位原arr[j]为0,那么输出新arr[j]为1,且说明原arr[i]在当前位为1;
// Ⅱ.若在某一位上的新arr[i]为0,那么说明原arr[i]和arr[j]在当前位相同,此时有
// 1)若当前位arr[j]为1,那么输出新arr[j]为1,且说明原arr[i]在当前位为1;
// 1)若当前位arr[j]为0,那么输出新arr[j]为0,且说明原arr[i]在当前位为0;
// 可以看到,输出的新arr[j]和原arr[i]按位相同,即两者完全相同
arr[i] = arr[i] ^ arr[j];
// 同上
}
// 冒泡排序
void BubbleSort(vector<int>& arr)
{
if (arr.size() < 2) return;
for (int i = 0; i < arr.size() - 1; i++)
for (int j = 0; j < arr.size() - i - 1; j++)
{
if (arr[j + 1] < arr[j]) Swap(arr, j, j + 1);
}
}
void main()
{
vector<int> arr = vector<int>(10);
for (auto& elem : arr)
{
elem = rand()%101; // 生成0~100之间的随机数
}
// === 显示原无序数组 === //
cout << "原无序数组为:" << endl;
for_each(arr.begin(), arr.end(), [](const int& elem) { cout << elem << " "; }); // 用算法中的for_each进行数组的显示
cout << endl;
// === 冒泡排序 === //
BubbleSort(arr);
// === 显示排序后的数组 === //
cout << "有序数组为:" << endl;
for_each(arr.begin(), arr.end(), [](const int& elem) { cout << elem << " "; });
cout << endl;
system("pause");
}
输出
冒泡排序的性质总结:
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
空间复杂度:
O
(
1
)
O(1)
O(1)
Swap交换的原理:
先要有几个引理(都容易验证):
(1)异或的结合律
( a ∧ b ) ∧ c = a ∧ ( b ∧ c ) (a\land b) \land c = a \land (b \land c) (a∧b)∧c=a∧(b∧c)
(2)异或的交换律
a ∧ b = b ∧ a a \land b = b \land a a∧b=b∧a
(3)自己异或自己
a ∧ a = 0 a \land a = 0 a∧a=0
(4)0异或任何数
0 ∧ a = a 0 \land a = a 0∧a=a
那么看到原代码,若将原 arr[i] 和 arr[j] 看作 a 和 b,那么有
a r r [ j ] = b ∧ ( a ∧ b ) arr[j] = b \land (a \land b) arr[j]=b∧(a∧b)
以及
a r r [ i ] = b ∧ ( a ∧ b ) ∧ ( a ∧ b ) arr[i] = b \land (a \land b) \land (a \land b) arr[i]=b∧(a∧b)∧(a∧b)
利用我们上面的引理,很容易得到
a r r [ j ] = a ∧ ( b ∧ b ) = a ∧ 0 = a arr[j] = a \land (b \land b) = a \land 0 = a arr[j]=a∧(b∧b)=a∧0=a
以及
a r r [ i ] = ( b ∧ b ) ∧ ( a ∧ a ) ∧ b = 0 ∧ 0 ∧ b = b arr[i] = (b \land b) \land (a \land a) \land b = 0 \land 0 \land b = b arr[i]=(b∧b)∧(a∧a)∧b=0∧0∧b=b