前言:快排最早由图灵奖获得者Tony Hoare设计出来的,他在形式化理论以及ALGOL60编程语言中,都有卓越的发明中都有卓越的贡献。是上世纪最伟大的计算机科学家之一;快排是他的一个小发明,被列为20世纪十大算法(有关十大算法参见链接博客https://www.sohu.com/a/228987774_488171)之一。另外:快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用,因此很多软件公司的笔试面试,包括像腾讯,微软等知名IT公司都喜欢考这个,还有大大小的程序方面的考试如软考,考研中也常常出现快速排序的身影。
希尔排序相当于插入排序的升级,他们同属于插入排序类;
堆排序相当于选择排序的升级,他们同属于选择排序类;
快速排序属于最慢的冒泡排序的升级,同属于交换排序类;
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
基本思想是:
1.先从数列中取出一个数作为基准数。2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。3.再对左右区间重复第二步,直到各区间只有一个数
第一趟排序之后:比基准数小的都在基准数左边,比基准数大的都在基准数右边:
之后的做法是
即递归:
递归执行的条件:i<j (保证i在j的左边)
#include<iostream> #include<vector> using namespace std; void print(vector<int> a) { for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; } cout << endl; } void quick_sort(vector<int> &arr,int start,int end) { //递归终止条件 print(arr); if (start >= end) return; int i = start; int j = end; //基准数 int temp = arr[start]; if (i<j) { while (i<j) { //从右往左找比基准数小的 while (i<j && arr[j]>=temp) { j--; } //填坑 if (i < j) { arr[i] = arr[j]; i++;//填完数字 i右移 } //从左向右找比基准数大的 while (i<j && arr[i]<temp) { i++; } //填坑 if (i < j) { arr[j] = arr[i]; j--; } } //循环退出 i=j 基础数位置放在i = j的位置 arr[i] = temp;//保证左边比基准数小,右边比基准数大 //第一个基准数放在该放的位置 //递归 quick_sort(arr, start, i - 1); quick_sort(arr, i + 1, end); } } int main() { vector<int> arr{0,9,1,5,8,3,7,4,6,2}; cout << "原数组:" << endl; print(arr); //快速排序 quick_sort(arr, 0, arr.size() - 1); cout << "排序后:" << endl; print(arr); system("pause"); }时间复杂度分析:时间性能取决于递归的深度:最优的情况是O(nlogn);最坏的情况是:O(n方)
//version.2 #include<iostream> #include<vector> using namespace std; void print(vector<int> a) { for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; } cout << endl; } int number(vector<int> &arr, int L, int R) { int i = L; int j = R; //基准数 int temp = arr[i]; while (i < j) { //从右往左找比基准数小的 while (i < j && arr[j] >= temp) { j--; } arr[i] = arr[j]; //从左往右找比基准数大的 while (i < j && arr[i] < temp) { i++; } arr[j] = arr[i]; } arr[i] = temp; return i; } void quick_sort(vector<int> &arr, int L, int R) { if (L >= R)return; int i = number(arr, L, R); quick_sort(arr, L, i - 1); quick_sort(arr, i + 1, R); } void main(){ vector<int> arr = { 0,9,1,5,8,3,7,4,6,2 }; print(arr); int l = 0; int r = arr.size()-1; quick_sort(arr, l, r); print(arr); system("pause"); }
快排非递归:
#include<iostream> #include<vector> #include<stack> using namespace std; int base_number(vector<int>&arr, int l, int r) { int i = l, j = r; int temp = arr[l]; while (i < j) { while (i < j &&arr[j] >= temp) { j--; } arr[i] = arr[j]; while (i < j &&arr[i] <= temp) { i++; } arr[j] = arr[i]; } arr[i] = temp; return i; } void quicksort(vector<int>& arr, int l, int r) { stack<int> st; int k; if (l < r) { st.push(l); st.push(r); while (!st.empty()) { int j = st.top(); st.pop(); int i = st.top(); st.pop(); k = base_number(arr, i, j);//基准数 if (i < k - 1) { st.push(i); st.push(k - 1); } if (j > k + 1) { st.push(k + 1); st.push(j); } } } } int main(){ vector<int> arr = { 1,26,5,65,26,98,36,36,871,2,3,56 }; quicksort(arr, 0, arr.size() - 1); for (int i = 0; i < arr.size() - 1; i++) { cout << arr[i] << " "; } system("pause"); return 0; }