我认为简单快速的排序的原理是:
此处以升序为例
选取一个基准点 q (起到中间变量的作用),
把小于这个基准点 q 的元素全部排到q的左边,
把大于这个基准点 q 的元素全部排到q的右边 ,
接着对q左边的序列重复操作,
即选取基准q1,
把小于q1的元素全部排到q1左边
把大于q1的元素全部排到q1右边
对q左边的序列也是如此
如此反复反复反复(很明显,这是我们熟悉的循环,递归操作)
接下来让我们看看具体如何实现
——————————————————
给出一个乱序整型数组 int a[7] = { 5 ,7 ,3 ,0 ,4 ,8 ,6 };
一般情况下我们选取第一个元素作为基准点q(当然基准点的选取是随机的)
1.比较a[ r ] = 6与 q = 5 的大小 , 如果a[ r ]>=q , 那么a[ r ]应该放 q 的右边
而a[ r ] = 6现在就在 q = 5 的右边 ,所以我们继续比较下一位
2.比较a[ r ] = 8与 q = 5 的大小 , 如果a[ r ]>=q , 那么a[ r ]应该放 q 的右边
而a[ r ] = 8现在就在 q = 5 的右边 ,所以我们继续比较下一位
3.比较a[ r ] = 4与 q = 5 的大小 , 如果a[ r ]>=q , 那么a[ r ]应该放 q 的右边
此时a[ r ] = 4 < q = 5 ,如果l < r (即l 与 r 没有相遇),
就把a[ r ] = 4利用 a[ l ] 移动到 q 的右边,即a[ l ] = a[ r ]
可能有的小伙伴看到表格会疑惑那元素5不是没有了嘛,
这时候想一想我在最前面说了q起到一个中间变量的作用,5一直存在q里面
4.r先移动,r一直向左移动,直到出现小于q的值或者l = r , 如果出现小于q的值且l < r
让a[ l ] = a[ r ]后 , 就该l开始移动(这里先解释一下基本流程,4步之后就自己看表格吧)
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
q = 5 | 5 | 7 | 3 | 0 | 4 | 8 | 6 |
l = 0 , r = 6 6 > 5 r- - | l | r | |||||
l = 0 , r = 5 8 > 5 r- - | l | r | |||||
l = 0 ,r = 4 4 < 5 a[ l ] = a[ r ] a[ 0 ] = a[ 4 ] | l | r | |||||
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
变化之后的数组 | 4 | 7 | 3 | 0 | 4 | 8 | 6 |
此时l = 0 , r = 4 (r- - 结束后 ,l++) | l | r | |||||
l = 1 , r = 4 , 7 > 5 , a[ r ] = a[ l ] a[ 4 ] = a [ 1 ] | l | r |
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
变化之后的数组 | 4 | 7 | 3 | 0 | 7 | 8 | 6 |
此时l = 1 , r = 4 (l++ 结束后 ,r - -) | l | r | |||||
l = 1 , r = 3 , 0 < 5 , a[ l ] = a[ r ] a[ 1 ] = a [ 3 ] | l | r |
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
变化之后的数组 | 4 | 0 | 3 | 0 | 7 | 8 | 6 |
此时l = 1 , r = 3 (r- - 结束后 ,l++) | l | r | |||||
l = 2 , r = 3 , 3 < 5 , l++ | l | r | |||||
此时l = r ,a[ l ] = q , 把q装在 l = r 的位置 | l r | ||||||
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
变化之后的数组 | 4 | 0 | 3 | 5 | 7 | 8 | 6 |
此时就实现了比q = 5小的元素全在q的左边,比q = 5大的元素全在q的右边
然后对于5左边的序列进行重复操作,对于5右边的序列进行重复操作,
4 0 3 ----> 3 0 4 7 8 6 ----> 6 7 8
3 0 ----> 0 3 6 7 ----> 6 7
----->0 3 4 ----->6 7 8
----->0 3 4 5 6 7 8
代码如下
```C
void quicksort(int a[],int L,int R){
if(L>=R){
return ;
}
int l = L,r = R,q;
q = a[l];//基准值
while(l<r){
while(l<r&&a[r]>=q){//当a[r]>=q时,r左移
r--;
}
if(l<r){
a[l] = a[r];
}
while(l<r&&a[l]<=q){//当a[l]<=q时,l右移
l++;
}
if(l<r){
a[r] = a[l];
}
if(l>=r){ //l和r相等的位置就是q值应该存放的位置
a[r] = q;//一轮快速排序也可以理解成挑出一个基准点,然后
} //通过不断地与其他元素比较大小找到它应该在的位置
}
quicksort(a,L,r-1);//对q左边的元素进行重复操作[L,r-1]为左区间
quicksort(a,r+1,R);//对q右边的元素进行重复操作[r+1,R]为右区间
}
```