01冒泡排序

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

參考博客:

https://www.geeksforgeeks.org/bubble-sort/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章