快速排序
1. 快速排序
快速排序(Quicksort),又称划分交换排序(partition-exchange sort),简称快排,一种排序算法,最早由东尼·霍尔提出。在平均状况下,排序n个项目要O(nlogn)次比较。在最坏状况下则需要O(n2)次比较,但这种状况并不常见。事实上,快速排序O(nlogn)通常明显比其他算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地达成。详情见快速排序【维基百科】
使用快速排序法对一列数字进行排序的过程
|
|
分类 | 排序算法 |
---|---|
数据结构 | 不定 |
最坏时间复杂度 | |
最优时间复杂度 | |
平均时间复杂度 | |
最坏空间复杂度 | 根据实现的方式不同而不同 |
2. 快速排序(基础版)
#include<iostream> #include<vector> #include <stdlib.h> #include <time.h> using namespace std; int Partition(vector<int> &array, int low, int high){ int pivotkey = array[low]; // 优化点1 while(low<high){ while(low<high && array[high] >= pivotkey) high--; swap(array[low], array[high]); // 优化点2 while(low<high && array[low] <= pivotkey) low++; swap(array[low], array[high]); } return low; } void QSort(vector<int> &array, int low, int high){ int pivot; if(low<high){ // 优化点3 pivot = Partition(array, low, high); QSort(array, low, pivot-1); QSort(array, pivot+1, high); } } void QuickSort(vector<int> &array){ QSort(array, 0, array.size()-1); } // 判断array是否有序 bool isOrder(vector<int> &array){ for(int i = 1; i < array.size(); i++){ if(array[i] < array[i-1]) return false; } return true; } // 生成n个介于min,max之间的整型数 vector<int> RAND(int max, int min, int n) { vector<int> res; //srand(time(NULL)); // 注释该行之后,每次生成的随机数都一样 for(int i = 0; i < n; ++i) { int u = (double)rand() / (RAND_MAX + 1) * (max - min) + min; res.push_back(u); } return res; } int main(int argc, char const *argv[]) { vector<int> a = RAND(1, 10000, 20000000); clock_t start = clock(); QuickSort(a); clock_t end = clock(); cout << "Time goes: " << (double)(end - start) / CLOCKS_PER_SEC << "sec" << endl; bool sorted = isOrder(a); cout<<sorted<<endl; return 0; }
使用 20000000(2千万)个介于1, 10000之间的数字进行测试,运行结果如下:
Time goes: 75.315sec 1 [Finished in 77.9s]
3. 快速排序(优化版)
#include<iostream> #include<vector> #include <stdlib.h> #include <time.h> #include <ctime> using namespace std; int Partition(vector<int> &array, int low, int high){ // 优化1:使用三数区中法,有效避免pivotkey取得最大最小值 int mid = low + (high - low) / 2; if(array[low] > array[high]) swap(array[low], array[high]); if(array[mid] > array[high]) swap(array[mid], array[high]); if(array[mid] > array[low]) swap(array[mid], array[low]); int pivotkey = array[low]; while(low < high){ while(low < high && array[high] >= pivotkey) high--; array[low] = array[high]; // 优化2:采用指定位置赋值,减少不必要的交换 while(low < high && array[low] <= pivotkey) low++; array[high] = array[low]; } array[low] = pivotkey; return low; } void InsertSort2(vector<int> &array, int low, int high){ for(int i = low+1; i <= high; i++){ if(array[i] < array[i-1]){ int temp = array[i]; int j = i; while(j > low && temp < array[j-1]){ array[j] = array[j-1]; j--; } array[j] = temp; } } } void QSort(vector<int> &array, int low, int high){ int pivot; if((high-low) > 13){ pivot = Partition(array, low, high); QSort(array, low, pivot-1); QSort(array, pivot+1, high); } // 优化3:当元素部分有序时,切换到插入排序 else InsertSort2(array, low, high); } bool isOrder(vector<int> &array){ for(int i = 1; i < array.size(); i++){ if(array[i] < array[i-1]) return false; } return true; } void QuickSort(vector<int> &array){ QSort(array, 0, array.size()-1); } // 生成n个介于min,max之间的整型数 vector<int> RAND(int max, int min, int n) { vector<int> res; //srand(time(NULL)); // 注释该行之后,每次生成的随机数都一样 for(int i = 0; i < n; ++i) { int u = (double)rand() / (RAND_MAX + 1) * (max - min) + min; res.push_back(u); } return res; } int main(int argc, char const *argv[]) { vector<int> a = RAND(1, 10000, 20000000); clock_t start = clock(); QuickSort(a); clock_t end = clock(); cout << "Time goes: " << (double)(end - start) / CLOCKS_PER_SEC << "sec" << endl; bool sorted = isOrder(a); cout<<sorted<<endl; return 0; }
使用相同的数字进行测试,运行结果如下:
Time goes: 64.458sec 1 [Finished in 66.9s]