1.普通的冒泡排序
冒泡排序是最简单的排序算法,它通过比较相邻元素并进行交换。
例子:需要排序的数组为[2, 1, 7, 9, 5, 8]。
第一轮排序:
[2, 1, 7, 9, 5, 8]->[1, 2, 7, 9, 5, 8],交换,因为2>1
[1, 2, 7, 9, 5, 8]->[1, 2, 7, 9, 5, 8]
[1, 2, 7, 9, 5, 8]->[1, 2, 7, 9, 5, 8]
[1, 2, 7, 9, 5, 8]->[1, 2, 7, 5, 9, 8],交换,因为9>5
[1, 2, 7, 5, 9, 8]->[1, 2, 7, 5, 8, 9],交换,因为9>8
第二轮排序:
[1, 2, 7, 5, 8, 9]->[1, 2, 7, 5, 8, 9]
[1, 2, 7, 5, 8, 9]->[1, 2, 7, 5, 8, 9]
[1, 2, 7, 5, 8, 9]->[1, 2, 5, 7, 8, 9],交换,因为7>5
[1, 2, 5, 7, 8, 9]->[1, 2, 5, 7, 8, 9]
[1, 2, 5, 7, 8, 9]->[1, 2, 5, 7, 8, 9]
现在数组已经完成排序,但是算法不知道已经完成,还需要对数组遍历一遍,无需交换。
第三轮排序:
[1, 2, 5, 7, 8, 9]->[1, 2, 5, 7, 8, 9]
[1, 2, 5, 7, 8, 9]->[1, 2, 5, 7, 8, 9]
[1, 2, 5, 7, 8, 9]->[1, 2, 5, 7, 8, 9]
[1, 2, 5, 7, 8, 9]->[1, 2, 5, 7, 8, 9]
[1, 2, 5, 7, 8, 9]->[1, 2, 5, 7, 8, 9]
下面是冒泡排序的C++代码实现:
#include <iostream>
using namespace std;
//交换元素位置
void swap(int *xp, int *yp) {
int tmp = *xp;
*xp = *yp;
*yp = tmp;
}
//冒泡排序,从小到大排序
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; ++i) {
for (int j = 0; j < n - 1 - i; ++j) {
if (arr[j] > arr[j + 1]) {
swap(&arr[j], &arr[j + 1]);
}
}
}
}
//显示数组
void printArr(int arr[], int size) {
for (int i = 0; i < size; ++i) {
cout << arr[i] << " ";
}
cout << endl;
}
//主函数
int main()
{
int arr[] = { 2,1,7,9,5,8 };
int size = sizeof(arr) / sizeof(arr[0]);
cout << "排序前";
printArr(arr, size);
cout << "排序后";
bubbleSort(arr, size);
printArr(arr, size);
system("pause");
return 0;
}
输出:
排序前2 1 7 9 5 8
排序后1 2 5 7 8 9
请按任意键继续. . .
2.优化后的冒泡排序
前面的函数的时间复杂度总是O(N*N),可以维持一个标志变量,记录内循环是否发生了交换,如果没有发生交换就说明排序完成。
#include <iostream>
using namespace std;
//交换元素位置
void swap(int *xp, int *yp) {
int tmp = *xp;
*xp = *yp;
*yp = tmp;
}
//优化后的冒泡排序,从小到大排序
void bubbleSort(int arr[], int n) {
bool hasChange = true;
for (int i = 0; i < n - 1 && hasChange; ++i) {
hasChange = false;
for (int j = 0; j < n - 1 - i; ++j) {
if (arr[j] > arr[j + 1]) {
swap(&arr[j], &arr[j + 1]);
hasChange = true;
}
}
}
}
//显示数组
void printArr(int arr[], int size) {
for (int i = 0; i < size; ++i) {
cout << arr[i] << " ";
}
cout << endl;
}
//主函数
int main()
{
int arr[] = { 2,1,7,9,5,8 };
int size = sizeof(arr) / sizeof(arr[0]);
cout << "排序前";
printArr(arr, size);
cout << "排序后";
bubbleSort(arr, size);
printArr(arr, size);
system("pause");
return 0;
}
输出:
排序前2 1 7 9 5 8
排序后1 2 5 7 8 9
请按任意键继续. . .
3.复杂度分析
3.1 空间复杂度
假设数组的元素个数是 n,由于在整个排序的过程中,我们是直接在给定的数组里面进行元素的两两交换,所以空间复杂度是 O(1)。
3.2 时间复杂度
1. 给定的数组按照顺序已经排好
在这种情况下,我们只需要进行 n−1 次的比较,两两交换次数为 0,时间复杂度是 O(n)。这是最好的情况。
2. 给定的数组按照逆序排列
在这种情况下,我们需要进行 n(n-1)/2 次比较,时间复杂度是 O(n*n)。这是最坏的情况。
3. 给定的数组杂乱无章
在这种情况下,平均时间复杂度是 O(n*n)。
综上,冒泡排序的时间复杂度为O(n*n),是一种稳定的排序算法,稳定是指如果数组里两个相等的数,那么排序前后这两个相等的数的相对位置保持不变。
参考博客: