交換排序

交換排序共包含兩種算法,冒泡排序和快速排序

一、冒泡排序

(Bubble Sort)是一種最簡單的排序算法,將第一個記錄和第二個記錄的關鍵字進行比較,若爲逆序,則進行交換,然後繼續向後移動進行比較,以此類推,直至第n-1個記錄和第n個記錄的關鍵字進行過比較爲止,這個過程稱爲第一趟冒泡排序。第二趟排序對前n-1個記錄進行同樣操作。

值得注意的是,冒泡排序的結束條件是“在一趟排序過程中沒有進行過交換的操作”。

容易看出,若初始序列爲“正序”,則只需要進行一趟排序,反之“逆序”的情況下,需要進行n-1趟排序,所以總的時間複雜度爲O(n^2)


二、快速排序

(Quick Sort)是對冒泡排序的一種改進,基本思想是通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,分別排序。

選取一個樞紐pivotkey,通常選擇第一個關鍵字,選擇兩個指針low和high,他們的初值分別爲low和hign,則首先從high所指位置向前搜索找到第一個關鍵字小於pivotkey的記錄和樞紐記錄互相交換,然後從low所指位置起向後搜索,找到第一個關鍵字大於pivotkey的記錄和樞紐記錄互相交換,重複直到low=high爲止。

Partition將序列一分爲二,左面都比pivotkey小,右面都比pivotkey大,返回樞紐的位置。對兩邊分別進行快排,即Partition。

時間複雜度分析:平均時間爲T(n)=k*n*ln^n,k爲某個常數,在所有同數量級的現金排序方法中,快排的常熟因子k最小,因此就平均時間而言,快排是目前被認爲是最好的一種內部排序方法。

平均時間複雜度O(n*logn)

當基本有序的時候,是冒泡排序,時間複雜度爲O(n^2),所以爲了改進他,通常在L[low],L[hign],L[(low+high)/2]三個數之間選擇一箇中間的數作爲樞紐。

同冒泡排序,如果一個子序列沒有進行交換,就沒有必要對這個子序列進行排序了。

空間複雜度:快速排序需要一個棧空間來實現遞歸,如果每次都是均勻分割兩個子序列,則棧的最大深度爲(以2爲底n的對數)+1,最壞情況下,棧的最大深度爲n,如果每次都能先對長度短的子序列進行快速排序,棧的最大深度可以降低爲O(logn)

測試:

int Partition(int L[], int low, int high)
{
	L[0] = L[low];
	int pivotkey = L[low];
	while (low < high)
	{
		while (low < high && L[high] >= pivotkey)
			--high;
		L[low] = L[high];//此時high位置的數據比pivotkey的小,所以要放到low的位置
		while (low < high && L[low] <= pivotkey)
			++low;
		L[high] = L[low];
	}
	L[low] = L[0];
	return low;//樞紐位置
}

//主函數調用QSort(L, 1, L.length)
void QSort(int L[], int low, int high)
{
	if (low < high)
	{
		int pivotlocation = Partition(L, low, high);
		QSort(L, low, pivotlocation - 1);
		QSort(L, pivotlocation + 1, high);
	}
}
int main()
{
	int L[] = {0, 49, 38, 65, 97, 76, 13, 27, 49};
	QSort(L, 1, 8);
	for (int i = 1; i <= 8; i++)
		cout << L[i] << endl;
}


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