快速排序——java实现

快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小。之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的。

快速排序的基本思想

首先在要排序的区域中选取一个基准,而后将整个区域分成两个分区,其中左分区中的元素均小于或者等于基准,右分区的元素均大于或者等于基准,而后通过递归调用快速排序的过程分别对两个分区再次进行排序,最后将两个分区产生的结果合并即可得到最后的排序序列。

但是选取基准有不同的方法,先介绍一下固定位置选取基准法

固定位置选取基准

每次都选取当前所排序区域最左边的元素作为基准。

上图啦~~
快速排序——java实现
可以看到经过一次排序后,基准左边的数都比基准小,基准右边的数都比基准大!!!
然后再对基准左边区域和右边区域分布排序

递归实现

public class Quick {

    //求基准
    public static int partion(int[] array, int low, int high) {
        int tmp = 0;
        tmp = array[low]; //tmp做为基准
        while (low < high) {
 
            while (low < high && array[high] >= tmp) { //先看右边,与基准进行比较,如果大于基准则继续向左比较
                high--;
            }
            if (low >= high) {
                break;
            } else { //直到小于基准,进行交换
                array[low] = array[high];
            }

            while (low < high && array[low] <= tmp) { //再看左边,与基准进行比较,如果小于基准则继续向右比较
                low++;
            }
            if (low < high){ //直到大于基准,进行交换
                array[high] = array[low];
            }
        }
        if (low == high) {
            array[low] = tmp;
        }
        return low;
    }

    /**
     * 时间复杂度:O(nlog2n)
     * 空间复杂度:O(log2n)
     * 不稳定
     *
     * @param array
     * @param low
     * @param high
     */
    public static void quick(int[] array,int low,int high){
        int par = partion(array,low,high); //O(n)
        if (par > low + 1){ //
            quick(array,low,par-1); //log2n
        }
        if (par < high - 1){
            quick(array,par+1,high);
        }
    }

    //递归实现
    public static void quickSort(int[] array){
        quick(array,0,array.length-1);
    }
}

非递归实现

就是用栈来实现
看图解啦…
快速排序——java实现
以此类推,经过一系列出栈入栈直到栈为空,排序结束

public class Quick {

    //求基准
    public static int partion(int[] array, int low, int high) {
        int tmp = 0;
        tmp = array[low];//tmp做为基准
        while (low < high) {

            while (low < high && array[high] >= tmp) {//先看右边,与基准进行比较,如果大于基准则继续向左比较
                high--;
            }
            if (low >= high) {
                break;
            } else {//直到小于基准,进行交换
                array[low] = array[high];
            }

            while (low < high && array[low] <= tmp) {//再看左边,与基准进行比较,如果小于基准则继续向右比较
                low++;
            }
            if (low < high){//直到大于基准,进行交换
                array[high] = array[low];
            }
        }
        if (low == high) {
            array[low] = tmp;
        }
        return low;
    }
        //非递归实现
    public static void quickSort(int[] array) {
        int low = 0;
        int high = array.length-1;
        int par = partion(array,low,high);
        int size = (int)(Math.log((double) array.length)/Math.log((double)2));
        int[] stack = new int[2*size];//log2n
        int top = 0;
        if (par > low +1){
            stack[top++] = low;
            stack[top++] = par - 1;
        }
        if (par < high - 1){
            stack[top++] = par + 1;
            stack[top++] = high;
        }
        while (top > 0){
            high = stack[--top];
            low = stack[--top];
            par = partion(array,low,high);
            if (par > low +1){
                stack[top++] = low;
                stack[top++] = par - 1;
            }
            if (par < high - 1){
                stack[top++] = par + 1;
                stack[top++] = high;
            }
        }
    }
}