快速排序法我花费了比较长的时间,可能比较笨吧,没太理解百度上的写法。最后终于自己悟了。
我们进行快速排序,需要三个条件:
1,需要排序的数组 ( a[ ],例如 a[10]={1,-3,4,2,8,10,3,98,53,25 )
2,需要排序的起始位置 ( left ,例如 0)
3,需要排序的结尾位置 (right,例如 9)
然后我们把需要排序第一个数字当成比较的基准,也就是key=a[left]
我们让j在i-right之间左移,让i在 left和j之间右移。(移动范围这里,划重点!)
j左移的时候把每个a[j]与key相比较,如果有比key小的数,就把他往左边放,放哪儿呢?给a[i]就行了、只是把这个找到的大数a[j]给a[i]就行,不用交换!不用交换!不用交换!不知道哪里看来的缺德描述,说是交换,困扰了我好长时间。可能交换有别的方法,但是我没交换。
然后i右移的时候,也是,找到小的数a[i],直接给a[j]就好了。
然后重复j移动,i再移动。在移动过程中,j跟i不断变化,移动范围也在不断变化,所以我用了j0和i0两个变量来分别记录j跟i的大小.
等到i跟j相遇的时候,i左边已经没有比key大的数了,都给右边了,j右边也没比key小的数了,都给左边了。那i,j相遇的位置肯定就是key应该在的位置。
接下来就是key左右两边的内部排序了。
假如key左边只有一个数,那就不用管了。但是假如有两个数及以上的数,也就是i>left+1的话,就需要把左边的数继续快速排序,这时候可以采用递归,调用函数本身。三个条件中,a[]没变,只是左边界变成了left,右边界变成了i。也就是执行 ks(a,left,i-1)。
同理,右边要是两个及以上的数,就执行ks(a,j+1,right)。
我把前几步粗略画个图解释一下
至此,解释部分就完毕了。挺长的,不知道我有没有解释清楚,我真的尽力了。
接下来是我的代码:
#include<stdio.h>
void ks(int a[],int left,int right)
{
int key,i,j,j0,i0,n;
key=a[left];
i0=left;
j0=right;
while(j0!=i0)
{
for(j=j0; j>i0; j--)
{
if(a[j]<key)
{
a[i0]=a[j];
break;
}
}
j0=j;
for(i=i0; i<j0; i++)
{
if(a[i]>key)
{
a[j0]=a[i];
break;
}
}
i0=i;
}
a[i0]=key;
if(i0>left+1)
ks(a,left,i0-1);
if(j0<right-1)
ks(a,j0+1,right);
}
int main()
{
int a[10]={1,-3,4,2,8,10,3,98,53,25};
int i;
ks(a,0,9);
printf("从小到大排序之后为");
for(i=0;i<10;i++)
printf("%d ",a[i]);
return 0;
}
冒泡排序法上课讲了好多了,就不写了。其他的啥时候想起来再写。