快速排序

时间复杂度 O(nlog2n) 最坏情况O(n^2) 不稳定排序
1、每一轮排序选择一个基准点(pivot)进行分区,让小于基准点的元素进入一个分区,大于基准点的元素进入另一个分区当分区完成时,基准点元素的位置就是最终位置。
2、在子分区内重复以上过程,直至子分区元素个数小于等于1,这体现的是分而治之的思想(divide-and-conquer)

public class FastSort {
    public static void main(String[] args){
        int[] arr = new int[]{5,43,21,1,213,8};
        lomuto(arr, 0, arr.length-1); // 洛穆托分区方案 单边循环快排
    }

    /**
     * 单边循环快排 选择最右元素作为基准点
     * @param arr
     */
    private static void lomuto(int[] arr, int l, int r) {
        if (l >= r){
            return;
        }
        int pv = partition2(arr, l, r);
        lomuto(arr, l, pv -1);
        lomuto(arr, pv+1, r);
    }

    /**
     * 单边循环
     * @param arr
     * @param l
     * @param r
     * @return
     */
    private static int partition(int[] arr, int l, int r){
        int pv = arr[r];
        int i = l;
        for (int j = l; j < r; j++) {
            if (arr[j] < pv){
                if (i != j){
                    swapNum(arr,i,j);
                }
                i++;
            }
        }
        if (i != r){
            swapNum(arr, i, r);
        }
        System.out.println(Arrays.toString(arr));
        return i;
    }

    /**
     * 双边循环
     * @param arr
     * @param l
     * @param r
     * @return
     */ 
    private static int partition2(int[] arr, int l, int r){
        int randNum = new Random().nextInt(r - l + 1) + l; // 随机选一个作为我们的主元
        swapNum(arr, l, randNum);
        int pv = arr[l];
        int i = l;
        int j = r;
        while (i < j){
            while (i<j && arr[j] > pv){
                j--;
            }
            while (i<j && arr[i] <= pv){
                i++;
            }
            swapNum(arr,i,j);
        }
        swapNum(arr, i , l);
        System.out.println(Arrays.toString(arr));
        return i;
    }

    /**
     * 交换数组中的两个数
     */
    public static void swapNum(int[] arr, int i, int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}
posted @ 2022-04-07 10:06  fjhnb  阅读(40)  评论(0)    收藏  举报