JAVA 快速排序真的很快

却是五侯家未识,春风不放过江来。 —罗邺《梅花》



快速排序
在排序算法中,快速排序是一种较快的排序算法,其时间复杂度为O(N*logN)。
主要思想
快速排序的主要思想为:

  • 1.确定基准数
  • 2.较大数、较小数(相比基准数)分离
  • 3.递归1、2步。

快速排序又叫分治法,也就是分块治理,把当前块分成较大数块、较小数块之后,再把较大数块,较小数块看成一个单独的块进行排序实现分治。
引用一张偷来的图,非常形象,而且看了停不下来。
偷的图

算法实现
假设现在有一组数据int [] num = {44,1,22,5,3,77,69,5,78,7,}; 现在要对其进行排序,且在排序时前面放较小数:

  • 1.找一个数作为基准,姑且找左边第一个吧(left= 0),方便些,即:basic = 44,坑:num[left = 0];
  • 2.找到了基准数,开始分数吧,先从后来吧(right->left),当前:left = 0;right = 9 ;找一个小的来填坑,运气不错,第一个就是(right = 9),那么num[left = 0] = num[right = 9],坑:num[right = 9],左边坑被填了一个满足条件的,不用下次再比较了,所以left++,left = 1,当前坑num[right = 9] = 7;
  • 3.再来找一个比basic大的数填到后面去,这回好像不太好找,left++加到left = 5时,终于看到了曙光num [left = 5] = 77,填到后面去,同理,坑被填了,表示当前已经是较大数,不需要下次再作比较,right–,right = 8 ,当前坑num[left= 5] = 77;

以此2、3步骤重复,下一步找到的较小数为num[7] =5,填到num[5] = 77 的坑,再找一个比当前大的num[6] = 69,填入num[7] =5,此时,再走时,left = right,数据已经排好

num [] = {7,1,22,5,3,5,44,69,78,77};

可以看到,较大数块全部在basic = 44 的右边,较小数块全在左边
其后便是分治,将较大数块、较小数块看成一个单独块递归再次排序。
代码实现
在代码中放了个 static int times = 1;记录排序次数

/**
 * @author Jan
 * 快速排序,找基准数,将小于和大于他的分别放到他两边,再将两边重复此步骤
 */
public class QuickSort {
    static  int times = 1;
    public static void main(String[] args) {
        int [] num = {44,1,22,5,3,77,69,5,78,7,};
        //有序检测
        //一次
//        int [] num = {1,2,22,24,25,77,78,79,80,81,};
        //4次
//        int [] num = {10,9,8,7,6,5,4,3,2,1};
        sort(num,0,num.length-1);
        for (int i = 0; i < num.length; i++) {
            System.out.print(num[i] + ",");
        }
    }

    /**
    排序方法
    */
    public static  void sort(int [] num,int le,int ri){
        /* 递归出口 */
        if (le>=ri){
            return;
        }
        int left = le;
        int right = ri;
        /* 基准数 */
        int basic = num[left];
        /*  小的放左边*/
        while (left < right){
            /* 挖坑,内缩
            * 从后往前,找小于basic的数,知道找到为止
            * */
            while (left < right && num[right] > basic){
                right --;
            }
            /* 找不到的话left>=right */
            if (left < right){
                num[left] = num[right];
                /* 填坑,挪一下 */
                left ++;
                /*  test */
                System.out.println(times++);
            }
            /*  从前往后,找大于basic的数*/
            while (left < right && num[left] < basic){
                left ++;
            }
            if (left < right){
                num[right] = num[left];
                right--;
                /* test */
                System.out.println(times++);
            }

        }
        num[left] = basic;
        sort(num,le,left-1);
        sort(num,right+1,ri);
    }
}

执行结果

QuickSort
1
2
3
4
5
6
7
8
9
10
11
1,3,5,5,7,22,44,69,77,78,
Process finished with exit code 0

总结
在排序中记得调整填坑之后的位置,即内缩:left-><-right,最后left = right为出口

猜你喜欢

转载自blog.csdn.net/logicr/article/details/80937543