快速排序:使用的是分治思想 (歸併排序也是);ios
(1)選一個元素M做爲基準數。算法
(2)把小於等於M的元素放在數組的左邊,大於M的元素放在數組右邊;這是M的位置已經是正確的,再也不改變。數組
(3)對M左邊、右邊的的數組分別使用(1)(2),知道數組中只有一個元素。dom
性能:ide
最壞時間複雜度是O(n2),平均時間複雜度是(nlogn),最好時間複雜度是(nlogn),是一種不穩定排序。函數
快速排序的三步分治過程:分解,解決,合併。因爲子數組是原址排序,因此不須要合併操做。性能
注:在代碼中,p r 均是數組下標,p 是首元素的下標, r 是最後一個元素的下標測試
QuickSort( A, p, r)ui
if p < r spa
q = Partition( A, p, r )
QuickSort( A, p, q-1)
QuickSort( A, q+1, r)
算法的關鍵是 Partition 過程,他實現了對子數組 A[p, r] 的原址重排
Partition ( A, p, r )
x = A[ r ]
i = p - 1
for j = p to r -1
if A[ j ] <= x
i = i + 1
exchange A[ i ] with A[ j]
exchange A[ i+1] with A[ r ]
return i + 1
快速排序的隨機化版本(使得算法對全部的輸入都有較好的指望性能),新的劃分程序中,只在真正進行劃分前進行一次交換,QuickSort( A, p, r)代碼不變;
RandomPartition( A, p, r)
i = Random(p, r)
exchance A[ r ] with A[ i ]
return Partition( A, p, r)
代碼:
#include<iostream> #include<vector> using namespace std; template<class T> int Partition(vector<T>&A, int p, int r) // p 和 r 均爲數組段的下標,p是數組首元素下標,r是數組最後一個元素下標 { T x = A[r]; int flag = p - 1; for (int j = p; j <= r-1; j++) //遍歷數組中的元素 { if (A[j] <= x) // 將數組中小於 A[r]的元素移到數組的左邊 { flag = flag + 1; T temp = A[flag]; A[flag] = A[j]; A[j] = temp; } } T tem = A[flag + 1]; A[flag + 1] = A[r]; A[r] = tem; return flag + 1; } template<class T> void QuickSort(vector<T>& Arry,int p,int r) { if (p <= r-1) { int q = Partition(Arry,p,r); //返回的元素位置已經被正確分類,即下面函數參數有 q-1,q+1, for (int i = 0; i <= r; i++) cout << Arry[i] << " "; cout << endl; QuickSort(Arry,p,q-1); //這裏也是分治的思想,q位置的元素位置已正確,只需對(q,q-1)與(q+1,r)排序 QuickSort(Arry, q+1,r); } }
測試代碼:
int main() { vector<int> arry= { 210, 12,19, 4, 7, 10, 15,21, 41, 51, 61, 81, 71, 91, 100,310,250,630,0,17}; for (int i = 0; i < 20; i++) cout << arry[i] << " "; cout << endl; QuickSort<int>(arry, 0, 19); for (int i = 0; i < 20; i++) cout << arry[i] << " "; cout << endl; cout << "BigThink" << endl; system("pause"); return 0; }
vector 容器作函數參數:
void Example( vector<int> vec);
void Example( vector<int> *vec);
void Example( const vector<int> * vec); //在函數內不能改變 vec指向的對象
void Example( vector<int>& vec);
void Example( const vector<int>& vec); // 在函數內不能改變 vec 對象