b站左神算法学习与C++实现——冒泡排序

冒泡排序

代码

#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) (ab)c=a(bc)

(2)异或的交换律

a ∧ b = b ∧ a a \land b = b \land a ab=ba

(3)自己异或自己

a ∧ a = 0 a \land a = 0 aa=0

(4)0异或任何数

0 ∧ a = a 0 \land a = a 0a=a

那么看到原代码,若将原 arr[i] 和 arr[j] 看作 a 和 b,那么有

a r r [ j ] = b ∧ ( a ∧ b ) arr[j] = b \land (a \land b) arr[j]=b(ab)

以及

a r r [ i ] = b ∧ ( a ∧ b ) ∧ ( a ∧ b ) arr[i] = b \land (a \land b) \land (a \land b) arr[i]=b(ab)(ab)

利用我们上面的引理,很容易得到

a r r [ j ] = a ∧ ( b ∧ b ) = a ∧ 0 = a arr[j] = a \land (b \land b) = a \land 0 = a arr[j]=a(bb)=a0=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]=(bb)(aa)b=00b=b

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值