十大排序-快速排序
阿新 • • 發佈:2020-07-20
快速排序演算法是一種基於交換的高效的排序演算法,它採用了分治法的思想
1.基本實現
1、從數列中取出一個數作為基準數(樞軸,pivot)。2、將陣列進行劃分(partition),將比基準數大的元素都移至樞軸右邊,將小於等於基準數的元素都移至樞軸左邊。
3、再對左右的子區間重複第二步的劃分操作,直至每個子區間只有一個元素。
快排最重要的一步就是劃分了。劃分的過程用通俗的語言講就是“挖坑”和“填坑”。
2.口訣要領
找基準,做交換,左右繼續。3.操作注意點(思考原因,寫一寫)
當基準數選擇最左邊的數字時,那麼就應該先從右邊開始搜尋;當基準數選擇最右邊的數字時,那麼就應該先從左邊開始搜尋。
不論是從小到大排序還是從大到小排序!
4.快速排序時間複雜度
快速排序的時間複雜度在最壞情況下是O(N^2),平均的時間複雜度是O(N*lgN)。
這句話很好理解:假設被排序的數列中有N個數。遍歷一次的時間複雜度是O(N),需要遍歷多少次呢?至少lg(N+1)次,最多N次。
(1) 為什麼最少是lg(N+1)次?快速排序是採用的分治法進行遍歷的,我們將它看作一棵二叉樹,它需要遍歷的次數就是二叉樹的深度,而根據完全二叉樹的定義,它的深度至少是lg(N+1)。
因此,快速排序的遍歷次數最少是lg(N+1)次。
(2) 為什麼最多是N次?這個應該非常簡單,還是將快速排序看作一棵二叉樹,它的深度最大是N。因此,快速排序的遍歷次數最多是N次。
5.快速排序的穩定性
例如,1 3 2 2 4進行快速排序從小到大排序時,3會和第二個2進行交換位置。這樣兩個2的相對位置就改變了。
6.程式碼展示
不用陣列而用vector,是因為函式中陣列的呼叫無法判斷陣列的長度,無法進行判斷是否陣列越界。#include<iostream> #include<vector> using namespace std; //快速排序(從小到大) void quickSort(int left, int right, vector<int>& arr) { int length = arr.size(); if (left >= right || right >= length) { //cout << "函式初始化錯誤" << endl; return; } int i, j, base, temp; i = left, j = right; base = arr[left]; //取最左邊的數為基準數 while (i < j) { while (arr[j] >= base && i < j) j--; while (arr[i] <= base && i < j) i++; if (i < j) { temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } //基準數歸位 arr[left] = arr[i]; arr[i] = base; quickSort(left, i - 1, arr);//遞迴左邊 quickSort(i + 1, right, arr);//遞迴右邊 } //快速排序(從大到小) void quickSort2(int left, int right, vector<int>& arr) { if (left >= right) //遞迴邊界條件 return; if (left < 0 || right >= arr.size()) { cout << "error args! 陣列越界!" << endl; return; }//非法輸入判斷,防止陣列越界 int i, j, base, temp; i = left, j = right; base = arr[left]; //取最左邊的數為基準數 while (i < j) { while (arr[j] <= base && i < j) j--; while (arr[i] >= base && i < j) i++; if (i < j) { temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } //基準數歸位 arr[left] = arr[i]; arr[i] = base; quickSort2(left, i - 1, arr);//遞迴左邊 quickSort2(i + 1, right, arr);//遞迴右邊 } int main() { vector<int> arr = { 1,3,2,2,4,5,6,0,1 }; cout << arr.size() << endl; quickSort(0, arr.size()-1, arr); //quickSort2(0, arr.size()-1, arr); for (auto it : arr) { cout << it; } }