交換排序:冒泡排序、選擇排序【排序算法】

冒泡排序基本思想:

在要排序的一組數中,對當前還未排好序的範圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就將它們互換。

快速排序基本思想:

1)選擇一個基準元素,通常選擇第一個元素或者最後一個元素

2)通過一趟排序講待排序的記錄分割成獨立的兩部分,其中一部分記錄的元素值均比基準元素值小。另一部分記錄的 元素值比基準值大。

3)此時基準元素在其排好序後的正確位置

4)然後分別對這兩部分記錄用同樣的方法繼續進行排序,直到整個序列有序。

快速排序是目前基於比較的內部排序中被認爲是最好的方法,當待排序的關鍵字是隨機分佈時,快速排序的平均時間最短;快速排序是一個不穩定的排序方法。

 

快速排序之所比較快,因爲相比冒泡排序,每次交換是跳躍式的。每次排序的時候設置一個基準點,將小於等於基準點的數全部放到基準點的左邊,將大於等於基準點的數全部放到基準點的右邊。這樣在每次交換的時候就不會像冒泡排序一樣每次只能在相鄰的數之間進行交換,交換的距離就大的多了。因此總的比較和交換次數就少了,速度自然就提高了。當然在最壞的情況下,仍可能是相鄰的兩個數進行了交換。因此快速排序的最差時間複雜度和冒泡排序是一樣的都是O(N2),它的平均時間複雜度爲O(NlogN)。


各排序算法比較:




代碼如下,親測有效:

#include <iostream>
using namespace std;

void swap(int *, int *);
void print(int[], int);
void bubbleSort(int[], int);
void bubbleSort2(int[], int);
void bubbleSort3(int[], int);
void quickSort1(int[], int, int);
void quickSort2(int[], int, int, int);

int main(void){

	int arr[10] = { 49, 38, 65, 97, 76, 13, 27, 49, 55, 04 };
	cout << "Original Array: " << endl;
	print(arr, 10);
	bubbleSort3(arr, 10);
	cout << "bubbleSort results: " << endl;
	print(arr, 10);
	quickSort2(arr, 0, 9, 8);
	cout << "quickSort results: " << endl;
	print(arr, 10);
	return 0;
}

//打印數組
void print(int a[], int n){
	for (int index = 0; index < n; ++index)
		cout << a[index] << "  ";
	cout << endl;
}

//交換
void swap(int *num1, int *num2){
	int tmp = *num1;
	*num1 = *num2;
	*num2 = tmp;
}

//冒泡排序
void bubbleSort(int array[], int n){
	for (int i = 0; i < n; ++i)
		for (int j = 1; j < n - i;++j)
		if (array[j] < array[j - 1])
			swap(array[j], array[j - 1]);
}

//冒泡排序2,設置一個標誌位flag,當在排序到某一刻已經沒有交換的時候,說明已經有序,把flag置爲false,退出排序
void bubbleSort2(int array[], int n){
	bool flag = true;
	int sizeOfArray = n;
	while (flag){
		flag = false;
		for (int j = 1; j < sizeOfArray; ++j){
			if (array[j - 1] > array[j]){
				swap(array[j], array[j - 1]);
				flag = true;
			}
		}
		--sizeOfArray;
	}
}

//冒泡排序3,記錄每次排序最後一次交換元素的位置,在這個位置之後一定是有序的,無需再排,只需排此位置之前的
void bubbleSort3(int array[], int n){
	int flag = n;
	while (flag > 0){
		int sizeOfUnsorted = flag;//上次排序最後一次交換的位置
		flag = 0;
		for (int index = 1; index < sizeOfUnsorted; ++index){
			if (array[index - 1] > array[index]){
				swap(array[index - 1], array[index]);
				flag = index;
			}
		}
	}
}

//快速排序1
void quickSort1(int array[], int left, int right){
	if (left < right){
		int i = left, j = right;
		int base = array[left]; //將最左邊的數作爲基準書,保存在base中
		while (i < j){
			while (i < j && array[j] >= base) //從右向左找第一個比base小的數,找到之後放到base的左邊(與base交換)
				--j;
			while (i < j && array[i] <= base) //從左向右找第一個比base大的數,找到之後放到base的右邊(與base交換)
				++i;
			if (i < j)
				swap(array[i], array[j]);
		}
	//	array[left] = array[i];
	//	array[i] = base;
		quickSort1(array, left, i - 1); //遞歸調用
		quickSort1(array, i + 1, right);
	}
}

//快速排序2
void quickSort2(int array[], int left, int right, int k){
	if (right - left > k){
			int i = left, j = right;
			int base = array[left]; //將最左邊的數作爲基準書,保存在base中
			while (i < j){
				while (i < j && array[j] >= base) //從右向左找第一個比base小的數,找到之後放到base的左邊(與base交換)
					--j;
				while (i < j && array[i] <= base) //從左向右找第一個比base大的數,找到之後放到base的右邊(與base交換)
					++i;
				if (i < j)
					swap(array[i], array[j]);
			}
	//		array[left] = array[i];
	//		array[i] = base;
			quickSort2(array, left, i - 1, k); //遞歸調用
			quickSort2(array, i + 1, right, k);
	}
	for (int index = 1; index <= right; ++index){	//此時的序列已基本有序,再用插入排序對基本有序序列排序
		int tmp = array[index];
		int j = index - 1;
		if (tmp < array[j]){
			array[j + 1] = array[j];
			--j;
		}
		array[j + 1] = tmp;
	}
}
</pre><pre name="code" class="cpp">
<span style="font-family:Microsoft YaHei;font-size:14px;">運行結果:</span>
<img src="https://img-blog.csdn.net/20150908194202423?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

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