定义
冒泡排序(Bubble Sort)是一种交换排序, 它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。
简单交换排序
首先来看一种最简单的交换排序算法。严格意义上来说,它不算是标准的冒泡排序算法,因为它不满足“两两比较相邻记录”的冒泡排序思想。
#include <iostream>
#include <algorithm>
using namespace std;
// 冒泡排序
template<typename T>
void bubbleSort(T arr[], int n){
for(int i =0; i < n; i++){
for(int j = 0; j < n; j++){
if(arr[i] > arr[j]){
swap(arr[i], arr[j]);
}
}
}
}
它应该算是最最容易写出的排序代码了,不过这个代码却是有缺陷的,因为它是固定一个关键字,然后让它和剩余比较。比如{1,3,4,5,6,2} 这个数组,当i=2时,退出循环可以将2提到第二个位置,但是同时3会被交换到最后一个位置,造成了这个算法的低效性。
标准冒泡排序
冒泡排序的精髓在于“两两比较相邻记录”。那么冒泡排序有两种思路,一种是最小值逐渐“浮”到最前面,另一种是最大值逐渐“沉”到最后面。
首先来看一下 最小值浮到最前面的程序。
#include <iostream>
#include <algorithm>
using namespace std;
template <typename T>
void bubbleSort(T arr[], int n){
for(int i = 0; i < n; i++){
for(int j = n-1; j > i; j--){
if(arr[j-1] > arr[j]){
swap(arr[j-1], arr[j]);
}
}
}
}
然后再看 最大值沉到最后面的程序。
#include <iostream>
#include <algorithm>
using namespace std;
template<typename T>
void bubbleSort(T arr[], int n){
for(int i =0; i < n; i++){
for(int j = 0; j < n-1-i; j++){
if(arr[j] > arr[j+1]){
swap(arr[j], arr[j+1]);
}
}
}
}
我们可以看到,最小值上浮和最大值下沉的程序思路是一样的,只是做了很小的改动。第一层for循环代表的含义是:第一次循环将最小值或者最大值上浮到数组第一个位置或者下沉到最后一个位置。第二次将第二小值或者第二大值上浮到数组第二个位置或者下沉到倒数第二个位置,一次类推。那么第二层循环代表的含义是:以最小值上浮为例,从数组最后一个元素开始,如果该值比倒数第二值小,交换二者顺序(最小值上浮一位),以此类推。如果否,那么OK,不用交换,继续执行,最终目的是找到一个最小值给它浮上去。同理最大值下沉是在二层循环中找到一个最大值沉到最后。
冒泡排序优化
第二节给出的冒泡排序算法在任何情况下都要从头到尾交换,进行冒泡操作,那么假如现在有一个近乎有序的数组,再做一些无谓的冒泡操作是浪费时间的。因此基于此,对上述冒泡排序做出优化。
具体代码为(以最小值上浮为例):
#include <iostream>
#include <algorithm>
using namespace std;
// 冒泡排序写法3
template <typename T>
void bubbleSort(T arr[], int n){
bool swapped = true;
for(int i = 0; i < n && swapped; i++){
swapped = false;
for(int j = n-1; j > i; j--){
if(arr[j-1] > arr[j]){
swap(arr[j-1], arr[j]);
swapped = true;
}
}
}
}
这样可以使得该排序算法的最好时间复杂度为O(n), 此时是原数组本身就是有序的。
贴出最大值下沉代码吧。
#include <iostream>
#include <algorithm>
using namespace std;
template <typename T>
void bubbleSort(T arr[], int n){
bool swapped = true;
for(int i = 0; i < n && swapped; i++){
swapped = false;
for(int j = 0; j <n-i-i; j++){
if(arr[j] > arr[j+1]){
swap(arr[j], arr[j+1]);
swapped = true;
}
}
}
}