参考链接:
https://blog.csdn.net/qq_51419787/article/details/123786370
https://blog.csdn.net/weixin_30342639/article/details/105343780
本篇是作为面经参考的算法记录,当问到快排这类基础算法却不会的话,挺尴尬的(说的就是我),所以这次把算法和代码都敲一遍,加深记忆。
算法步骤
- 从数列中挑出一个元素,一般取第一个元素,称为 "基准";
- 将一个左指针指向数组最左端,右指针指向数组最右端;
- 从右指针开始,从右往左移动,直到找到小于基准的元素处停下来,此时将右指针的值赋值给左指针的值;
- 左指针开始从左往右移动,直到找到大于基准的元素处停下来,将左指针的值赋值给右指针;
- 重复3-4,直到左指针与右指针相遇,并将两个指针相遇处的值赋值为之前记录的基准值,此时数列被基准值分为两部分,左子列小于等于基准值,右子列大于等于基准值;
- 递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。
#include <bits/stdc++.h>
using namespace std;
int quick_sort(vector<int>& nums , int begin , int end)
{
int temp = nums[begin];//取最左端为基准值
while (begin < end)//左指针和右指针碰面前为一个循环
{
while (begin < end && nums[end] >= temp)//找到右指针小于基准值的元素
end--;
nums[begin] = nums[end];//将小于基准值的元素赋值给左指针
while (begin < end && nums[begin] <= temp)//找到左指针大于基准值的元素
begin++;
nums[end] = nums[begin];
}
nums[begin] = temp;//左、右指针碰面后将其赋值为基准值,循环结束
return begin;
}
void QuickSort(vector<int>& nums , int begin , int end)
{
if (begin < end)
{
int standard = quick_sort(nums,begin,end);//获取当前数组的基准值
QuickSort(nums , begin ,standard - 1);//左子数组进行快排
QuickSort(nums, standard + 1 , end);//右子数组进行快排
}
}
int main()
{
vector<int> nums = {81,99,54,11,56,85,46,79,51};
QuickSort(nums,0,8);
for (auto num : nums)
cout << num << ' ';
cout << endl;
//11 46 51 54 56 79 81 85 99
return 0;
}
优化方法
取最左值为基准值的做法,如果数列本身是由大到小排列,则时间复杂度为o(n²),可采取的优化手段有
- 取最左边,最右边和最中间的中间值为基准值
- 随机抽取基准值