一. 算法内容:
将一组未排序的数字,按照从小到大的顺序排序。
二 . 算法思路及步骤:
算法将元素分为两部分,假想有一条分界线,它的左边是已排序的元素,右边是未排序的元素。算法将相邻数字两两比较,如果前一个数字大于后一个数字,那么交换这两个数,否则向后移动一个数,继续执行比较操作。每趟比较将最大的一个值放到分界线右侧的位置。
三 . 实例分析:
假设有未排序数组 [ 3, 1, 2, 7, 4 ] 。
1. 首先将 3 和 1 比较,发现 3 > 1,交换两数,现在数组状态为 [ 1, 3, 2, 7, 4 ] 。
2. 往后移动,此时比较 3 和 2, 发现 3 > 2,交换两数,现在数组状态为 [ 1, 2, 3, 7, 4 ] 。
3. 往后移动,此时比较 3 和 7 ,发现 3 < 7,不用执行任何操作。
4. 往后移动,此时比较 7 和 4,发现 7 > 4,交换两数,现在数组状态为 [ 1, 2, 3, 4, 7 ] 。
5. 可以发现,数组中最大的数字 7 已经被放到了正确的位置。并且我们又发现,数组已完成排序,结束(实际上还有其余操作,这里为了简便,略去的其余操作)。
四. 代码实现
1 void my_swap(int &a, int &b) { 2 int temp = a; 3 a = b; 4 b = temp; 5 } 6 7 void bubble_sort(vector<int> &arr) { 8 int n = arr.size(); 9 for (int i = 0; i < n - 1; ++i) { 10 for (int j = 1; j < n - i; ++j) { 11 if (arr[j - 1] > arr[j]) { 12 my_swap(arr[j - 1], arr[j]); 13 } else { 14 continue; 15 } 16 } 17 18 } 19 }
第一个函数 my_swap,用于交换两数。
第二个函数 bubble_sort,用于实现冒泡排序。该函数接受一个数组,并知道元素个数。外层循环控制变量 i ,控制大循环,它的范围是从第一个数(下标为 0 ) 至倒数第二个数(下标为 n - 1)。因为我们需要两两比较,假如 i 的范围到了最后一个数,那最后一个数应该跟谁比较?内层循环控制变量 j ,控制每一趟小循环,它的范围是从第二个数(下标为 1)至分界线左侧。这样设定 j 范围的原因是 : 分界线右侧的数字已排序,不需要参与比较,而分界线左侧的数字仍然不是完全有序(尽管相对较小的数字靠左),所以需要每一轮 j 都需要从头开始处理。
【注】
需要注意的是,我们的代码没有经过优化,如上例所示,第一趟排序已经让所有元素有序,但是算法并未停止,它会一直执行到最后一趟。我们可以设定一个变量,表示本趟是否进行交换,如果没有交换发生,则说明排序已经完成,算法可以及时停止。