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),是一種穩定的排序算法,穩定是指如果數組裏兩個相等的數,那麼排序前後這兩個相等的數的相對位置保持不變。
參考博客: