排序算法之--快速排序(QuickSort)

363 阅读2分钟

快速排序(QuickSort)

选择序列中的某个元素,将序列一分为2,小于该元素的放在前面,大于该元素的放在后面,相等的随便前后。那么这个元素就是 轴点元素(pivot)

快速排序的流程:

  • 选择一个元素作为pivot。
  • 用pivot将序列一分为2。
  • 重复1~2直到不能再分割,即子序列元素个数为1(也可以认为此时的子序列中的元素也是自己的pivot)。

下图中带颜色的都是轴点元素

ed7055d6919543309605709e520ebdaa_tplv-k3u1fbpfcp-watermark.png

快速排序算法拆分思路:

image.png

image.png

image.png

  • 如果轴点元素是取第一个,那么从数组的最后一位取值,找到第一个比轴点元素小的元素,将高指针位置的元素放在低指针的位置;low指针++
  • 从低指针位置开始找一个比轴点元素大的元素,将低指针位置上的元素放在高指针的位置;high指针++
  • 重复上面两个操作直到高低指针位置重合,则将轴点元素放在该位置,自此第一轮比较结束
  • 重复上面三个步骤,直至数据排序完成

核心算法如下:

    //快速排序     31  21  59  68  12  40
    //    x=31
    public static void quickSort(int[] array,int begin,int end){
        if(end-begin<=0) return;
        int x=array[begin];
        int low=begin;//0
        int high=end;//5
        //由于会从两头取数据,需要一个方向
        boolean direction=true;
        L1:  //设置一个标示位,当方向发生改变时,跳出到当前该位置
        while(low<high){
            if(direction){//从右往左找
                for(int i=high;i>low;i--){
                    if(array[i]<=x){
                        array[low++]=array[i];
                        high=i;
                        direction=!direction;
                        continue L1;
                    }
                }
                high=low;//如果上面的if从未进入,让两个指针重合
            }else{
                for(int i=low;i<high;i++){
                    if(array[i]>=x){
                        array[high--]=array[i];
                        low=i;
                        direction=!direction;
                        continue L1;
                    }
                }
                low=high;
            }
        }
        //把最后找到的值 放入中间位置
        array[low]=x;
        //开始完成左右两边的操作
        quickSort(array,begin,low-1);
        quickSort(array,low+1,end);
    }

项目运行;

     @Test
    public void addition_isCorrect() throws Exception {
        int[] array=new int[]{6,11,8,2,9,4,1,5,7,10,3};
        for (int i : array) {
            System.out.print(i+" ");
        }
        System.out.println("");
        quickSort(array,0,array.length-1);
        for (int i : array) {
            System.out.print(i+" ");
        }
    }

image.png

时间复杂度: 如果轴点两边数据比较均匀,那么时间复杂度是O(NlogN)。

如果轴点两边数据极度不均匀,那么最坏情况是O(N²)