性能分析:
时间复杂度:O(n*log(n))
空间复杂度:O(log(n))
这里的时间复杂度其实是快速排序最好的时间复杂度,最坏的时间复杂度是O(n^2)
代码里补充的随机化快速排序的期望时间复杂度为:O(n*log(n))
快速排序的性能优于归并排序是因为常数项,即算法所需的固定时间量。
#include<iostream> #include<vector> #include<algorithm> #include<random> #include<ctime> using namespace std; int partition(vector<int>& data,int left,1)">int right); void quick_sort(vector< right); main() { // 思想: 在元素序列上直接操作; 每次在无序序列中选取一个数,一般称之为中轴数, 将元素序列分成两个部分,使得一部分的元素全都小于等于另一部分的所有元素; 也就是说将序列分成小于等于中轴数和大于等于中轴数的两部分,使得中轴数变为有序; 再递归的对分成的两部分进行划分操作,分到1的时候就是天然有序的了 改进的思想是:每次随机找一个中轴数,将其交换到末尾,然后再往下 vector<int> data = { 7,5,1)">6,1)">4 }; 获取序列元素个数 int length = data.size(); int left = 0; int right = 3; vector<int> result; quick_sort(data,left,right); for (int i = 0; i < length; i++) { cout << data.at(i) << " "; } } right) { if (left < right) { 找到中轴数的索引 int index = partition(data,right); 以中轴数的索引为界递归的处理两个部分的序列 quick_sort(data,index - 1); quick_sort(data,index + ,right); } } 找到中轴数的正确位置,同时将序列划分为两部分. 中轴数有很多种取法,我们这里采用《算法导论》里的选取方法,即取序列最后一个元素. int key = data.at(right); 此处设置两个索引i和j,区间[left,i]为小于中轴数的序列,1)"> 区间[j,right-1]为大于中轴数的序列. /*这里有一种优化的方法,就是这个中轴数随机的找,然后交换到末尾,再往下执行*/ default_random_engine e(time(0)); //时间引擎 uniform_int_distribution<signed> u(left,right); int key = u(e); int tem = data.at(key); data.at(key) = data.at(right); data.at(right) = tem; int ave = data.at(right); */ int i = left - int j = left; j < right; j++)循环判断操作除了最右边基准值外的其他元素 { if (data.at(j) <= key) { 大于中轴数的元素让它继续待在[j,right-1]区间什么也不做; 小于中轴数的元素全部从[j,right-1]区间放到[left,i]区间去. ++i; int temp = data.at(i); data.at(i) = data.at(j); data.at(j) = temp; } } 此时中轴数的正确位置应该在i+1,将其归位. 思考为什么是i+1而不是i. int temp = data.at(i + ); data.at(i + 1) = data.at(right); data.at(right) = temp; 返回中轴数的正确索引. return i + ; }