用分治算法实现的快速排序对上面数字进行排序
快速排序算法
选定一个基准数val,把小于val的调整到左边,把大于val的调整到右边
我们选定41位基准
左边定义一个l,右边定义一个r
我们找的第一个5,发现就小于41了,所以把5调整到41这个地方。
然后l往前加一下。
此时r的位置的5已结给过去了,所以r的位置空闲下来了,在左边l进行对比,67大于41,所以把67填到r的位置。
此时r的位置有效了,r往前走,之前l的67已结放在原来的r位置保存了,现在l的位置是空闲的
现在r开始找比41小的,64比41大,不动,r继续左移,一直走到24的位置。
24比41小。把24放到l的位置,然后l向右走1步。
此时r的位置的24已经给过去了,此时的位置是空闲的。
从l开始找比41大的元素。
l一直走到69,69大于41,把69赋值到r的位置,然后r左移1步,此时l和r跑到同一个位置上了。
相遇的这个地方就存放val值41
这个算法的时间复杂度是O(n)
原问题只能把41调整到现在的这个位置。并不能解决问题。
所以接下来进行问题规模的缩减!
快排一趟:每一层基准数的平衡调整的时间复杂度是O(n)
快排多少趟,就是树的深度。二分搜索树。所以总的效率就是O(nlogn)
继续进行子问题的划分
相当于二叉树的中序遍历,就是一组有序的序列了
理想状态下,平衡的二叉树,原始数据比较乱,时间复杂度是:O(nlogn)
如果原始序列是降序的,我们通过快速排序让降序序列成为升序序列,每一次都要把基准数从头调到末尾,每一层基准数的平衡的调整是O(n),树的深度是一个链表,O(n),所以时间复杂度是O(n^2)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//快排划分函数,调整基准数
int partation(vector<int> &vec, int i, int j) {
int val = vec[i];//作为基准数
int l = i;
int r = j;
while (l < r) {
while (l < r && vec[r] >= val) {//右 - 左 找第一个比val小的
r--;
}
if (l < r) {
vec[l++] = vec[r];
}
while (l < r && vec[l] < val) {//左 - 右 找第一个比val大的
l++;
}
if (l < r) {
vec[r--] = vec[l];
}
}
vec[l] = val;//放置基准数
return l;//返回基准数的下标
}
void quickSort(vector<int> &vec, int i, int j) {
if (i >= j)//结束的条件,参加快排的元素只剩下1个了
{
return;
}
int pos = partation(vec, i, j);
quickSort(vec, i, pos - 1);
quickSort(vec, pos + 1, j);
}
int main()
{
vector<int> vec;
for (int i = 0; i < 11; ++i) {
vec.push_back(rand() % 100);
}
for (int v : vec) {
cout << v << " ";
}
cout << endl;
quickSort(vec, 0, vec.size() - 1);
for (int v : vec) {
cout << v << " ";
}
cout << endl;
return 0;
}