快速排序是如何进行的?
有下图中的这样一个数组,对其进行从小到大到排序
面对这样的一个无序的数组到底应该怎么排序;
第一步:先找到一个基准值(为了方便,可以选取左边的第一个值为基准值。
第二部:定义两个指针left和end,分别指向最左边和最右边;右边的指针往左边移动,左边的指针往右边移动,而原理基准值的那个指针先移动。
第三部:右边的指针开始移动,直到遇见一个值是小于基准值的,把该处赋值给left,然后left++,接着left往右边移动,直到遇见大于基准值的值,把该值赋值给end,end--;两个一直交互移动,直到end==left,再把基准值赋值给end和left;这是完成了第一次排序,这一步的目的是为了实现把大于基准值的值都放在及它的左边,小于基准值的值放在左边。代码实现片段如下所示
void quick_p(int* arr, int left, int end)
{
int i = left;
int j = end;
int tmp = arr[left];//基准值
while (i < j)
{
while (i<j && arr[j]>tmp)//先从右边往左边移动
{
j--;
}
//跳出循环,说明j此时指向的元素小于tmp
if (i < j)
{
arr[i] = arr[j];
i++;//这里i指向的内容被j所指向的内容覆盖,所以i要++;
}
//照葫芦画瓢,接下来的是从左往右移动
while (i < j && arr[i] < tmp)
{
i++;
}
if (i < j)
{
arr[j] = arr[i];
j--;
}
}
arr[i]=arr[j]=tmp;//把基准值赋值给i和j指向的地方;
}
很明显,要通过递归能够实现最后的排序;所以,现在首先要考虑这个递归结束的条件是什么,明显易得,当这个left>=end的时候递归就结束;所以在上面的代码中要加上一个条件,就是递归结束的条件;这个条件必须加在函数做开始的时候
if(left>=end)
return ;
最后一步:对基准值两边的元素分别进行排序,一直递归下去,直到触发了递归结束的条件
quick_p(arr,left,i-1);//此时i指向的是基准值,所以从left到i-1是左边的数据
quick_p(arr,i+1,end);//同样的道理得到基准值右边的数据;
例题:排序__牛客网
具体实现过程
void quick_p(int* arr,int left,int end)
{
if(left>=end)
return ;//快速排序是一个递归的过程,所以首先要考虑递归的结束条件
int i=left;
int j=end;
int tem=arr[i];//选一个基准值
while(i<j)
{
//先从右边往左边走
while(i<j&&arr[j]>tem)
j--;
if(i<j)
{
arr[i]=arr[j];
i++;
}
//然后是从左边往右边走
while(i<j&&arr[i]<tem)
i++;
if(i<j)
{
arr[j]=arr[i];
j--;
}
}
arr[i]=tem;
arr[j]=tem;//此时要对i和j共同指向的对象进行赋值
quick_p(arr,left,i-1);
quick_p(arr,i+1,end);
}
int* MySort(int* arr, int arrLen, int* returnSize ) {
// write code here
*returnSize=arrLen;
quick_p(arr,0,arrLen-1);
return arr;
}