quicksort快排
1.从待排的数里随便取分界点x,常用两边或中间
2.考虑两个指针i,j分居数两侧,如果指针i指向的数左小于x或右边的j大于x,则向中间走一格。如果i大于x或者j小于x,则停下,等两边停下,交换数。从而保证在x的左边都小于等于x,右边同理
3.由此,一串数通过x划分为左右两串数,对每一串数递归处理即可
代码实现
void quick_sort(int q[],int left,int right){
if(left==right)return ;
int i=left-1,j=right+1;
int s=q[(left+right)/2];
while(i<j)//结束循环意味着i>=j,此时代表完成{
do i++;while(q[i]<s);
do j--;while(q[j]>s);
if(i<j){
int temp=q[j];
q[j]=q[i];
q[i]=temp;
}
}
quick_sort(q,left,j);
quick_sort(q,j+1,right);
}
需要注意,
1.s应该是q[(left+right)/2]这个固定值,而不是left+right)/2这个索引,因为虽然s不变,但后面while交换时可能打乱变动q[s]值。
2.建议递归的(q,left,j)不写成(q,left,j-1),因为当排序只有两个,左边指针一来就停止时,右边会到最左边,造成左边的数分串是零,右边跟原来一模一样,造成无限递归。同理,s=q[r]时,尽量避开(q,left,j)
即s=q[left]或left+right/2----j,j+1;s=q[right]或者left+right+1/2----i-1,i。
3.为什么是j,j+1而不是j-1,j?
考虑结束时仅有i=j(指向同一个地点)和----ji-----i在j后面一个,显然划分数串的就是ji中间的缝,对应索引j,j+1或者i-1,i(这里选择ij需要注意2的问题,如果是取中间还是j,毕竟c是向小取整)

浙公网安备 33010602011771号