1.分而治之思想
选取一个基准数(pivot),利用双指针相向遍历数组,然后将比基准数大的数放基准数右边,比基准数小的数放基准数左边;然后再对左右分割的两个数组各自选取pivot进行同样的操作,使用递归法直到只剩一个数。
2.递归三部曲
- 终止条件
- 参数和返回值
- 单次递归逻辑
3.基准pivot的选取
对于pivot的选取有多种方案。下面进行分析:
方案1:选取边界点作为pivot
eg:nums=[5,2,3,1,9]
选取左边边界或者右边边界,此处假设pivot = nums[0];此时pivot已经记录了第一个数,第一个数的位置可以空出,相当于挖了一个洞,所以从数组右边找一个比pivot(第一个数)小的的数把洞补上;nums[0] = nums[j];数组变为nums=[1,2,3,1,9];此时显然右边重复了(挖了个洞),所以从数组左边找一个比pivot数大的数将其补上;这就是单层的逻辑;
结束条件:利用双指针相向遍历,双指针相遇的地方则为结束位置,而结束位置也将用来分割数组,作为下一层递归的边界;
代码实现:
#include <iostream>
#include<vector>
using namespace std;
class Solution {
public:
void quicksort(vector<int> &arr,int l,int r)
{
int i=l,j=r;
int pivot = arr[l];
if(l<r)
{
while(i<j)
{
while(i<j&&arr[j]>=pivot)
{
j--;
}
if(i<j)
{
arr[i] = arr[j];
i++;
}
while(i<j&&arr[i]<pivot)
{
i++;
}
if(i<j)
{
arr[j] = arr[i];
j--;
}
}
arr[i] = pivot;
quicksort(arr,l,i-1);
quicksort(arr,i+1,r);
}
}
vector<int> sortArray(vector<int>& nums) {
int l=0,r=nums.size()-1;
quicksort(nums,l,r);
return nums;
}
};
int main()
{
Solution s1;
vector<int> array={1,19,97,9,17,1,8,9};
int left=0;
int right = array.size()-1;
vector<int> result;
result = s1.sortArray(array);
for(int i=0;i<right;i++)
{
cout<<" "<<result[i];
}
return 0;
}
实验结果:
方案2:选取中间点作为pivot
选取中间的点作为pivot,pivot =nums [ l+(l-r)/2];只需要利用双指针法,每次拿一个左边比较pivot的大的数与右边比pivot小的数交换位置即可;下面将用C语言解答
1.交换数组元素:
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
2.单层递归函数
// 将数组划分为两部分,并返回枢轴的最终位置
int partition(int *nums, int low, int high) {
int mid = low + (high - low) / 2; // 选择枢轴元素的索引
int pivot = nums[mid]; // 枢轴元素的值
int i = low - 1; // 左指针
int j = high + 1; // 右指针
while (1) {
// 移动左指针,直到找到大于等于枢轴的元素
while (nums[++i] < pivot);
// 移动右指针,直到找到小于等于枢轴的元素
while (nums[--j] > pivot);
if (i >= j)
return j; // 返回枢轴的最终位置
// 交换左右指针所指的元素
swap(&nums[i], &nums[j]);
}
}
注意的点:1.左右指针起点,2.使用前置运算而不是后置,3.返回值
3.递归函数
// 快速排序算法
void quick_sort(int *nums, int low, int high) {
if (low < high) {
int pi = partition(nums, low, high); // 划分数组并获取枢轴位置
quick_sort(nums, low, pi); // 对左半部分进行递归排序
quick_sort(nums, pi + 1, high); // 对右半部分进行递归排序
}
注意的点:1.下一次边界的划分
方案3.随机选取pivot
待补充