快速排序算法

  在一本书上发现的一种改进版的快速排序算法,自己把它整理出来了。这里通过小数组的时候是用插入排序算法,大数组的时候使用快速排序算法进行对算法的优化。而且是用三数中值分割法取枢纽元保证这个两个数组分得的数学期望大小是相等的。(即取首,末,中三个点的中值作为枢纽元,且在比较过程中把另外两个排好序)用以保证算法效率的稳定性。而且能去除特殊情况的判断,使得算法效率更高。另外把交换方法定义为final也可以使得编译时代码被嵌入到调用处,使得运行更快。

  我尝试用大量泛型随机整数(随机数范围大小等于数组的大小),进行排序,其排序效率表明大概是java内置的Arrays.sort()函数的泛型排序的3倍,即大概用时为后者用时的1/3。因此在此记录下来。

/**
 * 实现的代码:
 */
public class QuickSort {
    private static final int CUTOFF=10;

    //不允许创建其对象
    private QuickSort(){

    }

    //快速排序的驱动程序
    public static <E extends Comparable<E>> void quickSort(E[] array){
        quickSort(array,0,array.length-1);
    }

    //快速排序的主程序
    private static <E extends Comparable<E>> void quickSort
            (E[] array,int left,int right){
        //若数组太小,则是用插入排序
        if(left+CUTOFF>right){
            insertionSort(array,left,right);
            return;
        }

        E pivot=median3(array,left,right);

        //设置左右两端开始的值
        int i=left;
        int j=right-1;

        while (true){
            while (array[++i].compareTo(pivot)<0);
            while (array[--j].compareTo(pivot)>0);

            if(j>i){
                swapReferences(array,i,j);
            }else {
                swapReferences(array,i,right-1);
                break;
            }
        }

        quickSort(array,left,i-1);
        quickSort(array,i+1,right);
    }

    //寻找快速排序的枢纽元,三数中值分割法,返回枢纽元
    private static <E extends Comparable<E>> E median3
            (E[] array,int left,int right){
        int center=(left+right)/2;

        if(array[center].compareTo(array[left])<0){
            swapReferences(array,center,left);
        }

        if(array[right].compareTo(array[left])<0){
            swapReferences(array,right,left);
        }

        if(array[right].compareTo(array[center])<0){
            swapReferences(array,right,center);
        }

        //把枢纽元放在right-1处
        swapReferences(array,center,right-1);

        return array[right-1];
    }


    /**
     *
     * @param array 用于交换的数组
     * @param left 交换的左位点
     * @param right 交换的右位点
     *
     * 该方法用于交换数组中的两个位点的值
     */
    private final static <E extends Comparable<E>> void swapReferences
            (E[] array,int left,int right){
        E temp=array[left];
        array[left]=array[right];
        array[right]=temp;
    }

    //对过于小的数组实行插入排序,一个是防止最坏情况的产生,一个是能有效的增加效率
    private static <E extends Comparable<E>> void insertionSort
            (E[] array,int left,int right){
        for(int i=left+1;i<=right;i++){
            E temp=array[i];

            int j;
            for(j=i;j>left&&temp.compareTo(array[j-1])<0
                    ;j--){
                array[j]=array[j-1];
            }

            array[j]=temp;
        }
    }
}
package com.company.Sort;

import java.util.Arrays;

/**
 * 测试所用代码
 */
public class Main {
    public static void main(String[] args) {
        Integer[] random=new Integer[10000000];

        for(int i=0;i<random.length;i++){
            random[i]=(int)(Math.random()*random.length);
        }

        Integer[] r1=random.clone();
        Integer[] r2=random.clone();

        long time=System.currentTimeMillis();
        QuickSort.quickSort(r1);
        System.out.println(System.currentTimeMillis()-time);

        time=System.currentTimeMillis();
        Arrays.sort(r2);
        System.out.println(System.currentTimeMillis()-time);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值