您的位置:首页 > 其它

算法总结(4)快速排序

2016-04-02 18:05 323 查看
     在算法的评判中,速度绝对是很重要的一点,而接下来要说的这个排序算法,既然敢命名为快速排序,就必然有它的过人之处。

     一.算法思路

     原始数组被分为两个子数组,第一个数组小于等于某选定值(枢轴),第二个数组大于等于某选定值。重复分割。直到全部为一元数组。

     快速排序的本质是递归的,它应用于数组每层分割的两个数组中,应用了分而治之的思想。

     选择一个好的枢轴是很重要的任务。

     二.伪代码

     quicklysort(a[])

             if(a.length>1)

                  选择枢轴;

                         while a中还有元素

                                 把element加入subarray1或者subarray2中;

                                        quicksoft(subarray1);

                                        quicksoft(subarray2);

     三.代码实现

/**
* @author garypotter
* @version 创建时间:2016年4月2日 下午6:21:19
* @TODO
* 类说明
*/
public class QuickSort {

public static void main(String[] args) {

//int[] a={5,2,3,8,1,9,10,13,4,11};
//int[] a={6,6,6,6,6,6,6,6,6,6};
int[] a={72,71,73,74,60,1,2,3,4,80};
int[] b={};
int[] c={1};
quicksort(a,0,a.length-1);
quicksort(b, 0, b.length-1);
quicksort(c,0,c.length-1);
System.out.println(9/2);
System.out.println("result:"+a[0]+" "+a[1]+" "+a[2]+" "+a[3]+" "+a[4]+" "+a[5]+" "+a[6]+" "+a[7]+" "+a[8]+" "+a[9]);

}

public static void quicksort(int[] a,int start,int end){
if(start>=end){

return;   //如果只剩下一个,就返回!注意,一定要返回!
}

int pivotindex=findpivot(start,end);//选出一个枢轴

swap(a,pivotindex,end);             //将枢轴放到尾部,注意,这里的尾部不仅仅是指a的尾部,而是分而划之的每一个小数组的尾部
int k=partition(a,start-1,end,end); //将当前数组分为两部分,返回的是右边数组的第一个元素在a中的下标;
//注意,是start-1,左边的初始下标比左边的第一个数的下标小一,比如,第一次,0-1=-1;
swap(a,k,end);      //分了两部分之后把枢轴换到k这个位置
quicksort(a,start,k-1); //左右边同样,迭代
quicksort(a,k+1,end);   //

}

public static int findpivot(int i,int j){
return (i+j)/2;//稍微优化一下,选择在中间的,尽量避免极端情况。
}
public static void swap(int[] a,int m,int n){
int temp=a[m];
a[m]=a
;
a
=temp;
}

//重点,分为两部分,注意,此时最尾部的只用于比较,不会交换,分为两部分之后才交换
public static int partition(int[] a,int l,int r,int pivotindex){
do{
//基本思想是:找到左边的比枢轴大的,找到右边比枢轴小的,交换
while(a[++l]<a[pivotindex]);
//最后一次,会找到右边这部分的最左边的数
//从-1开始,先增1,才是第一个元素,再判断是否大于尾部的;极端情况:所有输入相同,则一直比较到最后一个,等于,此时l等于length-1,进入下一步,在这个边界不会出错
while((l<r)&&a[pivotindex]<a[--r]);//&&自左向右运算,如果第一个表达式为false,则不再计算第二个表达式
//先--r,因为最右边的是枢轴,不用来比较,从右往左扫描,找出一个小于枢轴的。
swap(a,l,r);//最后l和r相遇,l=r,这时能跳出while
}while(l<r);
return l;//返回右边的第一个元素的下标
}

}


     
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: