关于快速排序算法的基本原理基本上大家都了解过,现在我总结以下写代码过程中需要注意的几点。
先放leecode代码
class Solution{
public:
void quick_sort(int s,int e,vector<int>& nums)
{
if(s>e) return;
int k=rand()%(e-s+1)+s;
swap(nums[k],nums[s]);
int cur=nums[s];
int i=s;
int j=e;
while(i<j)
{
while(i<j&&(nums[j]>=cur)) j--;
while(i<j&&(nums[i]<=cur)) i++;
swap(nums[i],nums[j]);
}
swap(nums[i],nums[s]);
quick_sort(s,i-1,nums);
quick_sort(i+1,e,nums);
}
vector<int> sortArray(vector<int>& nums)
{
srand((unsigned)time(nullptr));
int n=nums.size();
quick_sort(0,n-1,nums);
return nums;
}
};
以上代码可以直接放在leecode上运行,但是在完成之前犯了很多错误,导致没能通过。
- 会忘记在递归函数中(A调用A,直到遇到停止条件)创建停止条件。同时会导致后续的求随机数除以0导致出错。写递归函数,一定要记得加判停条件。
- 关于随机数的两个函数 srand((unsigned)time(nullptr)); n=rand();
- 根据随机数选取被排序数组中的一个值,定义为基准值,和两个哨兵变量i,j。
- 一轮排序,以基准值将数组左右划分。一轮排序后i=j.这里思路一定要清晰,关于j左移动的判停条件:cur是基准值,升序序列,默认我们选取第一个数作为基准值,哨兵j在序列的右边,我们目标是要找比cur小的数nums[j]然后通过交换移动至数组左边,因此当遇到比cur大的数nums[j]要继续j--,让大的数继续留在右边。
- 同理:关于哨兵i,我们要找到比cur大的数移动至数组右边,因此在while过程中遇到比cur小的数,继续i++跳过,让其留在数组的左边。
- 过程中涉及到两种交换一种是哨兵的交换,一种是一次排序完成后,将i和s(start)的位置交换。
- 最后递归调用自身函数,对分段后的(s,i-1)和(i+1,e)再分别进行排序。判停条件是s>e;
- 记住s,e和i,j的意义。