快速排序

今天学习了快速排序算法,实现了基本快速排序和三向切分快速排序,其中三向切分对于有大量重复数据的情况有很好的作用。

package Code;

import java.util.Random;

public class QuickSort {
    public static void sort(int[] a){
        for(int i=0,len=a.length;i<len;i++){  
            Random random=new Random();  
            int j=random.nextInt(len);  

            swap(a,i,j);  
        }  
        sort(a,0,a.length-1);
    }
    private static void sort(int[] a,int lo,int hi){
        if(hi<lo)
            return;
        int j=partition(a,lo,hi);
        sort(a,lo,j-1);
        sort(a,j+1,hi);
    }
    private static int partition(int[] a, int lo, int hi) {
        // TODO Auto-generated method stub
        int i=lo,j=hi+1;
        int v=a[lo];
        while(true){
            while(less(a[++i],v)) if(i==hi) break;
            while(less(v,a[--j])) if(j==lo) break;
            if(i>=j) break;
            exch(a,i,j);
        }
        exch(a,lo,j);
        return j;
    }
    private static void exch(int[] a, int i, int j) {
        // TODO Auto-generated method stub
        int temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }
    private static boolean less(int i, int v) {
        // TODO Auto-generated method stub
        if(i>=v)
            return true;
        return false;
    }
    private static void swap(int[] a, int i, int j) {
        // TODO Auto-generated method stub
        int temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }
    /**
     * 
     * @param a
     * @param lo
     * @param hi
     * 三向切分快速排序  
     *核心思想就是将待排序的数据分为三部分,左边都小于比较值,右边都  
     *大于比较值,中间的数和比较值相等.  
     *三向切分快速排序的特性就是遇到和比较值相同时,不进行数据交换,  
     *这样对于有大量重复数据的排序时,三向切分快速排序算法就会优于  
     *普通快速排序算法,但由于它整体判断代码比普通快速排序多一点,所  
     *以对于常见的大量非重复数据,它并不能比普通快速排序多大多的优势  
     */

    public static void quick3way(int[] a,int lo,int hi){
        if(hi<lo) return;
        int lt=lo,i=lo+1,gt=hi;
        int v=a[lo];
        //lt表示左侧存放小于比较值的下标位置  
        //gt表示右侧存储大于比较值的下标位置  
        //i是当前需要进行比较的下标位置,i值从左侧不断向右侧前行,  
        //当i与gt相遇时,表明每次分析已经完成. 
        while(i<=gt){
            //1 如果当前i值小于比较值,则将当前i下标值与lt下标值进行交换,  
            //  同时lt递增,准备存储下一个小的值, 当前索引i也进行递进  
            //2 如果当前i值大于比较值,则将当前i下标值与gt下标值进行交换,  
            //  同时gt递减,准备存储下一个大的值, 注意这里当前索引i并没有  
            //  递进,这是因为i是从左向右移动的,对于小于比较值的处理,因为  
            //  i已经知道左侧的值都是经过它处理的,一定都是小于比较值的,所  
            //  以进行第1步小于比较值的处理时,它直接递增,而当前处理大于  
            //  比较值时,最右侧的数据是什么情况它并不清楚,所以当右侧数据  
            //  交换到当前i索引值,i不能递进,它需要对右侧移来的值进行分析  
            //3 如果当前i值与比较值相等,则无需交换处理,直接当i索引递进  
            if(a[i]<v) swap(a,lt++,i++);
            else if(a[i]>v) swap(a,i,gt--);
            else i++;
        }//a[lo...lt-1]<v=a[lt..gt]<a[gt+1..hi]成立
        quick3way(a,lo,lt-1);
        quick3way(a,gt+1,hi);
    }
    public void quick3sort(int[] a,int lo,int hi){
        if(lo<hi) return;
        int lt=lo,i=lo+1,gt=hi;
        int v=a[lo];
        while(i<=gt){
            if(a[i]<v) swap(a,lt++,i++);
            else if(a[i]>v) swap(a,i,gt--);
            else i++;
        }
        quick3sort(a,lo,lt-1);
        quick3sort(a,gt+1,hi);
    }
    public static void main(String[] args){
        int[] a={4,1,3,2,5,6,8,2,7};
        quick3way(a,0,a.length-1);
        for(int i=0;i<a.length;i++){
            System.out.print(a[i]+",");
        }
        System.out.println();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值