快速排序java实现(原址纯递归)

对于快速排序的原理就是每次选一个值,然后左边是小于这个值右边是大于这个值,但写程序做了大量的修改,最终性能与希尔插入排序和双轴快排做比较,都是不稳定排序,但从随机数来看总体慢于双轴快排,略等于希尔插入排序,现在逻辑还不够简练,有时间优化下的话性能应该还能有一定的提升。下面是代码和测试数据。

 


import java.time.LocalDateTime;
import java.util.Arrays;

/*
 *数组方法
 */
public class ArrTool {

    //自建随机数生成器
    private static int seed = LocalDateTime.now().getSecond();
 
    //n到b范围的随机数
    public  static int myrandom(int n, int b){
        seed = 37 * seed + 137;
        if (seed < 0) {
            seed *= -1;
        }
        return seed%(b+1-n)+n;
    } 

    //调用接口
    private  static  void quickSort(int[] arr){
        ArrTool.quickSort2(arr,0,arr.length-1);
    }    

    //快速排序优化
    private  static void quickSort2(int[] arr,int left,int right){
        //随机选取比较参数
        Integer compareIndex = ArrTool.myrandom(left,right);
        Integer x = arr[compareIndex];
        Integer point = compareIndex;//替换点实际位置
        Integer index = 0; //下一替换点
        Integer count = 0; //交换次数
        Boolean isContinue = Boolean.FALSE;

        for (int i = left; i < right+1; i++) {
            if (i<right && arr[i] > arr[i+1]){
                isContinue = Boolean.TRUE;
            }
            if (arr[i] > x ) {
                if (count==0){
                    index = i;
                }
                count++;
            }else{
                if (count==0){
                    continue;
                }
                int temp = arr[index] ;
                arr[index]= arr[i];
                arr[i] = temp;
                if (arr[index]==x){
                    point =index;
                }
                index ++;
                if (temp==x && index>0){
                    index--;
                }
            }
        }
        if (x!=arr[right]){
            arr[point]= arr[right-count];
            arr[right-count] = x;
        }
        if (right-left-count>1 && isContinue){
            quickSort2(arr,left,right-count-1);
        }
        if (count>1 && isContinue){
            quickSort2(arr,right-count+1,right);
        }
    }

    public static void shellSort(int[] a) {
        long start = System.currentTimeMillis();
        int n =a.length;
        int j,gap;
        for (gap = n/2; gap > 0; gap /=2) {
            for (j = gap; j < n; j++) {
                if (a[j]<a[j-gap]) {
                    int temp = a[j];
                    int k = j -gap;
                    while (k>=0&&a[k]>temp) {
                        a[k+gap] = a[k];
                        k-=gap;
                    }
                    a[k+gap]=temp;
                }
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("希尔插入排序完成的时间:"+(end - start)+"毫秒");
    }



    public static void main(String[] args) {
        
        int[] arr =new int[]{9,5,9,6,7,9,10,1,5,8,4,3,2,1,5,9,8,6,4,7,5,2};
        quickSort(arr);
        System.out.println(Arrays.toString(arr));
        /** 性能测试
        int [] arr1=new int[100000];
        int [] arr2=new int[100000];
        int [] arr3=new int[100000];
        for (int i = 0; i < 100000; i++) {
            int x = ArrTool.myrandom(0,1000);
            arr1[i] =x;
            arr2[i] =x;
            arr3[i] =x;
        }
        ArrTool.shellSort(arr1);
        long start = System.currentTimeMillis();
        Arrays.sort(arr2);
        long end = System.currentTimeMillis();
        System.out.println("系统快速排序完成的时间:"+(end - start)+"毫秒");
        long start1 = System.currentTimeMillis();
        quickSort(arr3);
        long end1 = System.currentTimeMillis();
        System.out.println("手写板快速排序完成的时间:"+(end1 - start1)+"毫秒");

        */

        /**
        数据正确暴力验证
        int n=0;
        while (n<100000){
        int [] arr2=new int[1000];
        for (int i = 0; i < 1000; i++) {
            arr2[i] =ArrTool.myrandom(0,1000) ;
        }
        quickSort(arr2);
        for (int i = 0; i < 999; i++) {
            if (arr2[i]>arr2[i+1]){
                System.out.println(存在错误数据,验证失败);
            }eles{
                System.out.println(全部正确,验证成功);
        }
        n++;
        }
         */
    }

}

数据量10万

希尔插入排序完成的时间:    18毫秒   21毫秒   65毫秒
系统快速排序完成的时间:    19毫秒   34毫秒   68毫秒
手写板快速排序完成的时间: 56毫秒  66毫秒    50毫秒.

数据量100万

希尔插入排序完成的时间:   174毫秒   180毫秒   174毫秒
系统快速排序完成的时间:     93毫秒   122毫秒   174毫秒
手写板快速排序完成的时间:208毫秒   240毫秒   275毫秒

数据量1000万

希尔插入排序完成的时间:   1590毫秒  1574毫秒    1550毫秒
系统快速排序完成的时间:     431毫秒    456毫秒    440毫秒
手写板快速排序完成的时间:1662毫秒  1629毫秒   1639毫秒

数据量1亿

希尔插入排序完成的时间:16159毫秒     15961毫秒   17149毫秒
系统快速排序完成的时间:4096毫秒        4177毫秒    4201毫秒
手写板快速排序完成的时间:16168毫秒  15063毫秒   15851毫秒

总结:只是初步优化过的快排性能就已经很好了,而且是全递归运算,基本达到了理论运算水平,优化后基本不会内存泄露,基本理论上快排并没有多大优势,但合并优化其他排序方式能得到最大性能提升。比如java中的双轴快排。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值