快速排序

快速排序是一个经典的排序,而且针对特定的问题,又分为2路快排和3路快排。今天,我们不搞这些复杂的,就搞经典快排。

快速排序_第1张图片
快速排序.png

如图所示,快速排序如果遇到数组都有序的情况,那么快排将会退化成O(n^2),所以选择随机快排来更改这个情况。然后变成了一个概率事件,长期期望为O(n*logn)。
快排总体思路:
1.先将数组分开,小于基准的放左边,等于的放中间,大于的放右边,然后依次对左右进行
类似的操作。
2.关于partition函数,less相当于左边界,more相当于有边界,像 左) 数组 (右。
快排其实有两种思路,思路一是分成了小于区less区,大于区more区,然后每次将小于基准的放到小于区,小于区扩大一个,表现为less++;每次把大于基准的放到大于区,大于区扩大一个,表现为more--。
思路二是,选择一个基准,然后从数组的右端向左端扫描直到找到一个小于它的元素,停止,然后从数组的左端到右端扫描,直到找到一个大于它的元素,停止,然后交换两个元素的位置。当两个指针相遇时,交换基准和相遇位置的元素。

//思路一
public class QuickSort {

    public void quickSort(int[] arr){
        if(arr == null || arr.length < 2)
            return;
        quickSort(arr, 0, arr.length - 1);
    }

    public void quickSort(int[] arr, int L, int R){
        if(L < R){
            swap(arr, L + (int)(Math.random() * (R - L + 1)), R); // 随机选一个数与最后一个数交换
            int[] p = partition(arr, L, R); //把小的放左边,等于放中间,大的放右边
            quickSort(arr, L, p[0] - 1);//排左边
            quickSort(arr, p[1] + 1, R);//排右边
        }
    }

    public int[] partition(int[] arr, int L, int R){
        int less = L - 1;
        int more = R;
        while(L < more){
            if(arr[L] < arr[R])
                swap(arr, ++less, L++);
            else if(arr[L] > arr[R])
                swap(arr, --more, L);
            else
                L++;
        }
        swap(arr, more, R);
        return new int[]{less + 1, more};
    }

    public void swap(int[] arr, int i, int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] arr = {5, 3, 6, 2, 1, 9};
        new QuickSort().quickSort(arr);
        for (int e: arr) {
            System.out.println(e);
        }
    }
}

//思路二
public class quickSort2 {

    public void quickSort(int[] arr){
        if(arr == null || arr.length < 2)
            return;
        quickSort(arr, 0, arr.length - 1);
    }

    public void quickSort(int[] arr, int L, int R){
        if(L < R){
            swap(arr, L + (int)(Math.random() * (R - L + 1)), R);
            int i = partition(arr, L, R);
            quickSort(arr, L, i - 1);
            quickSort(arr, i + 1, R);
        }
    }

    public int partition(int[] arr, int L, int R){
        int index = R;
        R--;
        while(L < R){
            /*
            if(arr[R] > arr[index])
                R--;
            else if(arr[L] < arr[index])
                L++;
            else
                swap(arr, arr[R--], arr[L++]);*/
            while (arr[R] > arr[index])
                R--;
            while(arr[L] < arr[index])
                L++;

            swap(arr, arr[R--], arr[L++]);
        }
        swap(arr, arr[index], arr[L]);
        return L;
    }

    public void swap(int[] arr, int i, int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] arr = {5, 3, 6, 2, 7, 3, 1, 9};
        new QuickSort().quickSort(arr);
        for (int e: arr) {
            System.out.println(e);
        }
    }
}

你可能感兴趣的:(快速排序)