今天看了快速排序,现在对自己的已知的方法进行总结,欢迎拍砖。

        快速排序被认为是20世纪十大算法之一,在排序中,快速排序其实就是我们前面认为最慢的冒泡排序的升级,它们都属于交换排序类。即快排也是通过不断比较和移动交换来实现排序的,不过它的实现,增大了记录的比较和移动的距离,将关键字较大的记录从前面直接移动到后面,关键字较小的从后面直接移动到前面,从而减少了总的比较次数和移动交换次数。

3  1  2 5  4  6接下来再对6左边和6右边的元素进行相同操作的递归。

        快排方法(一)和方法(二)在实现方式中有些差别,我们首先对于方法(一)的过程分析:

        首先分别对原始序列的两端进行探测,先从右往左找一个比6小的数,再从左向右找一个比6大的数,(在后面会说明为什么先要从6 的右边向左开始找)然后进行交换,直至当左向标等于右向标,然后将其共同指向的数与这轮的基准值进行交换,交换完毕后,分别从left到i-1的序列和从i+1到right进行递归,直至完全排序。

        NOTE:

在实现快排方法(一)之前,我们先对快排一中为什么必须首先从右边开始向左边找做一个说明^_^

        如果我们在上述过程中,首先从左开始向右查找比6大的值,开始的左右互换不会出现问题,但是在最后与基准值交换就会出现问题!比如我们现在已经换到了这样的序列:6,1,2,7,9;此时若i从左向右进行查找, i到了7的位置会停下,j从右向左进行查找,j到了7的位置,和i相同,也会停下,这时6会与7进行交换,嘿嘿,这时7居然跑到了基准值6的右边!导致了结果错误,所以开始必须从右开始向左查找比基准值小的数。

快排(一)实现具体如下:

#include <stdio.h> 
int a[101],n;//定义全局变量,这两个变量需要在子函数中使用
void quicksort(int left,int right)
{
int i,j,t,temp;
if(left>right)
return;
temp=a[left]; //temp中存的就是基准数
i=left;
j=right;
while(i!=j)
{
//顺序很重要,要先从右边开始找
while(a[j]>=temp && i<j)
j--;
//再找右边的
while(a[i]<=temp && i<j)
i++;
//交换两个数在数组中的位置
if(i<j)
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
//最终将基准数归位
a[left]=a[i];
a[i]=temp;
quicksort(left,i-1);//继续处理左边的,这里是一个递归的过程
quicksort(i+1,right);//继续处理右边的 ,这里是一个递归的过程
}
int main()
{
int i,j,t;
//读入数据
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
quicksort(1,n); //快速排序调用
//输出排序后的结果
for(i=1;i<=n;i++)
printf("%d ",a[i]);
getchar();getchar();
return 0;
}

    


下面我们来总结一下快排方法(二)的过程:

快排方法二的总体其实和快排方法一是一样的,只是在循环条件和到每一轮最后中和基准值交换的时候有些不同。快排二是首先从左向右找出大值,接着再从右向左找出较小的值,(仔细想想与前面的顺序不同,接着是怎样来处理的)。因为快排方法一中的分析,我们可以了解到,如果是首先从左到右进行搜索时,会出现最后交换值的问题,为了避免交换值的问题,其中的一种思路是采用先从右向左搜索的方式,第二种思路则是依然是先从左到右搜索,但是在每一轮中跳出循环后,不是将左边left下标指向的值与基准值进行交换,而是将右边right下标指向的值与基准值进行交换,这样就可以避免最后在交换时出现最后将基准值换错的问题。

        快排(二)实现具体如下:


#include <stdio.h>
int a[101],n;//定义全局变量,这两个变量需要在子函数中使用
int Patition(int a[],int p,int r)
{
int i=p,j=r+1;
int tt;
int x = a[p];
while(true){
while(a[++i]<x&&i<r);
while(a[--j]>x);
if(i>=j) break;
tt=a[i];
a[i]=a[j];
a[j]=tt;
}
a[p] = a[j];
a[j] = x;
return j;
}
void QuickSort(int a[],int p,int r)
{
if(p<r){
int q = Patition(a,p,r);
QuickSort(a,p,q-1);
QuickSort(a,q+1,r);
}
}
int main(){
int i,j,t;
//读入数据
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
QuickSort(a,1,n); //快速排序调用
//输出排序后的结果
for(i=1;i<=n;i++)
printf("%d ",a[i]);
getchar();getchar();
return 0;
}



       快排的优化