思路过程
假设我们现在对“6 1 2 7 9 3 4 5 10 8”这个10个数进行排序。首先在这个序列中随便找一个数作为基准数(不要被这个名词吓到了,就是一个用来参照的数,待会你就知道它用来做啥的了)。为了方便,就让第一个数6作为基准数吧。接下来,需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,类似下面这种排列。
1 | 3 1 2 5 4 6 9 7 10 8
分别从初始序列“6 1 2 7 9 3 4 5 10 8”两端开始“探测”。先从右往左找一个小于6的数,再从左往右找一个大于6的数,然后交换他们。这里可以用两个变量i和j,分别指向序列次左边和最右边。我们为这两个变量起个好听的名字“哨兵i”和“哨兵j”。刚开始的时候让哨兵i指向序列的次左边(即下标为1),指向数字1。让哨兵j指向序列的最右边(即下标为9),指向数字8。
哨兵i从左往右依次寻找到第一个比基准大的数,哨兵j从右往左依次寻找到第一个比基准小的数,然后交换。
交换:注意:交换之前需要检查i是否小于j,只有i < j的时候才能交换。否则不交换,然后进入最后的基准的位置调整。
再继续往前寻找(哨兵i寻找比基准大,哨兵j寻找比基准小的),直到哨兵i,j相遇或者j < i。
![在这里插入图片描述](https://img-blog.csdnimg.cn/bc4186f
这里由于不满足i < j,因此3和9不会进行交换。退出循环。
现在我们发现以3和9的中间为界,除了基准6以外,比6小的都在左边,比6大的都在右边。因此,此时还需要调整基准的位置。
这里需要注意的是,当选择的基准在最左边时,需要和右指针也就是j做交换;
如果选择的基准在最右边,则基准和左指针i进行交换。
当我们第一次排序结束以后,就需要对原数组进行划分处理,以上一个基准为界,分为两个数组,如下
然后再对子数组进行上述的排序操作,这是一个递归的思想。
代码块
int quick(int *arr,int leftbound,int rightbound)
{
int leftptr = leftbound+1;
int rightptr = rightbound;
int pivot = arr[leftbound];
while(leftptr <= rightptr)
{
while(leftptr <= rightptr && arr[leftptr] < pivot)
{
leftptr++;
}
while(leftptr <= rightptr&& arr[rightptr] >= pivot)
{
rightptr--;
}
if(leftptr < rightptr)
{
swap(arr,leftptr,rightptr);
}
}
swap(arr,leftbound,rightptr);
return rightptr;
}
void quick_sort(int *arr,int left,int right)
{
if(right <= left)
{
return;
}
int mid = quick(arr,left,right);
quick_sort(arr,left,mid-1);
quick_sort(arr,mid+1,right);
}