算法总结(4)快速排序

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

     一.算法思路

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

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

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

     二.伪代码

     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[n];
		a[n]=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;//返回右边的第一个元素的下标
	}
	
	
}


     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值