实现快速排序算法的关键在于先在数组中找到一个数(基数),接下来把数组分为两部分,把小于该数的数字移到数组的左边,把大于该数的数字移动数组的右边。等于该数的数字不动。
先给一张通俗易懂的过程演示图
讲解第一次排序
3 4 1 7 6 2 0 基数:3
第一步:首先找一个基数,以数组第一个数为基数,保存基数。定义两个指针start,end分别指向数组的第一个数和最后一个数,也就是start指向3,end的指向0。
第二步:end指向的数字和基数比较,如果大于等于基数,end指针减一。否则把end指向的数字交换到start的位置
0 4 1 7 6 2 0
第三步:start指向的数字和基数比较,如果小于等于基数,start指针加一。否则把start指向的数字交换到end的位置
0 4 1 7 6 2 0
0 0 1 7 6 2 4
重复第二步
0 0 1 7 6 2 4
0 2 1 7 6 0 4
重复第三步
0 2 1 7 6 0 4
0 2 1 7 6 0 4
0 2 1 0 6 7 4
重复第二步
0 2 1 0 6 7 4
0 2 1 0 6 7 4
最后start和end位置相等,结束,把基数送回数组
0 2 1 3 6 7 4
此时数组分成两部分,使用递归就可以了。
代码如下:
#include <iostream>
#include <vector>
using namespace std;
int getindex(vector<int> &arr, int start, int end);
void quickSort(vector<int> &arr, int start, int end);
int main() {
vector<int> arr;
int tmp;
while (cin >> tmp) {
arr.push_back(tmp);
}
quickSort(arr, 0, arr.size() - 1);
for(int i = 0; i < arr.size(); i++)
cout << arr[i]<<" ";
system("pause");
return 0;
}
void quickSort(vector<int> &arr, int start, int end) {
if (start >= end)
return ;
int index = getindex(arr, start, end);
quickSort(arr, start, index-1);
quickSort(arr, index + 1, end);
}
int getindex(vector<int> &arr, int start, int end) {
int standard = arr[start];
while (start < end)
{
while((start < end)&&(arr[end] >= standard))
end--;
arr[start] = arr[end];
while((start < end)&&(arr[start] <= standard))
start++;
arr[end] = arr[start];
}
arr[start] = standard;
return start;
}
快速排序总结:
平均时间复杂度: O(nlog2n)
最坏情况:O(n2)
最好时间复杂度:O(nlog2n)
空间复杂度:O(log2n)
最坏情况:
在选取基准p的时候,每次选取的都是当前数组中最小的一个元素,那么每次划分都只是让数组中的元素少1,这样一来就需要反复遍历数组导致复杂度变成了O(n2)。
如果我们在选取基准p的时候,每次选取的都是当前数组中最中间的一个元素(是中位数,而不是元素位置上的中间),那么每次划分都把当前数组划分成了长度相等的两个子数组,这样一来复杂度变成了O(nlog2n)。