交換排序:氣泡排序、選擇排序【排序演算法】
氣泡排序基本思想:
在要排序的一組數中,對當前還未排好序的範圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就將它們互換。
快速排序基本思想:
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="" />