快速排序原理
找一个基准值,进行左右分区,一个左边的都大于基准值的子数组,一个右边的都小于基准值的子数组。再对两个子数组按照同样的方法分区,直到基准值旁边的数组值为空或只有一个元素。最后整体就是一个有序的数组。
代码
#include<stdio.h>
int main()
{
int n,i,a[100];
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
quicksort(a,0,n-1);
for(i=0;i<n;i++)
printf("%d ",a[i]);
}
void quicksort(int a[],int low ,int high)
{
int i =low;
int j= high;
int temp=a[i];//temp为标杆
if(low<high)
{
while(i<j)
{
while(a[j]>=temp&&i<j)//从右边开始与标杆比较
j--;//若比标杆大则比较下一个数字
a[i]=a[j];//此时退出循环为不符合条件,即右边小于标杆,也就是说这个数字不应该处于他现在的位置,要将之摆在左边,但不是调换位置。但这会造成标杆的数值丢失,所以一开始我们就用了temp来记录标杆的值
while(a[i]<=temp&&i<j)
i++;
a[j]=a[i];//同理但因为此时j的位置的值已经复制过去了(第一个循环),所以此时的j位置上的值是没有意义,也就意味着直接复制上去即可不会造成数据丢失。
}
a[i]=temp;//退出循环时i跟j在同一位置,此时左右两边已经分配好了,最好将标杆的值重新赋值上。
quicksort(a,low,i-1);//递归排序左边
quicksort(a,i+1,high);//递归排序右边
}
else//如果low>=high 说明已经排完了
return ;
}
遇到的困难
刚开始我以为是数值之间的替换,但后来发现是数值的复制,因为我潜意识以为数值的复制会造成数据的丢失,但当我自己再纸上演练一遍的时候发现,除了第一个数值会丢失(其实一开始已经保存了下来,最后还会添上去),其余的都不会丢失,因为复制的时候此时数组里有两个该数字,一个是有用的(已经找对了位置),一个是无用的(用来被下一个本应该再这个位置的数字替换)为什么他能被替换?因为前提这个数字的位置本身就是错误的已经替换了一次,所有他残留下来的数值是可被替换
想法
这里的递归没有检验两个子分区是否已经有序,所以即使已经有序了但仍会进行,因此会浪费的大量的时间。
ps 大一小白欢迎指点