快速排序及其简单优化_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 快速排序及其简单优化

快速排序及其简单优化

 2017/11/13 22:03:26  陶永攀  程序员俱乐部  我要评论(0)
  • 摘要:快速排序是我们大一进入学校就会的东西,但我发现自己到了大学之后学东西非常生硬,都是被别人灌输的,缺少了自己思考的过程,这几天被左神一语惊醒,我们学习算法应该是一个思考与探索的过程,不是简单的把这道题AC了就完事了,那我们大学之前那么辛苦可不是为了来大学玩的,所以以后要学会思考和学会探索;首先今天我们来讲的是快速排序,这里用三种方法来写快排的;①设定一个标志,两个哨兵分别从两端开始行走的方法,主代码如下:publicstaticvoidquickSort(int[]arr,intl,intr)
  • 标签:优化 快速排序

? ? ? ?快速排序是我们大一进入学校就会的东西,但我发现自己到了大学之后学东西非常 生硬,都是被别人灌输的,缺少了自己思考的过程,这几天被左神一语惊醒,我们学习算法应该是一个思考与探索的过程,不是简单的把这道题AC了就完事了,那我们大学之前那么辛苦可不是为了来大学玩的,所以以后要学会思考和学会探索;

? ? ? ?首先今天我们来讲的是快速排序,这里用三种方法来写快排的;

?①设定一个标志,两个 哨兵分别从两端开始行走的方法,主代码如下:

class="java" name="code">public static void quickSort(int[] arr,int l,int r){

        if ( l < r ){
            //随机出标志数
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int q = partition(arr ,l , r);
            quickSort(arr,l,q-1);
            quickSort(arr,q+1,r);
        }
    }

public static int partition(int[] arr,int l,int r){
        int p = arr[l];//设置标志位置
        int i = l;//左哨兵
        int j = r;//右哨兵
        while (i < j){
            while (arr[j] >= p && i < j){
                j--;
            }
            if (i<j){
                swap1(arr,i,j);
            }
            while (arr[i] <= p && i < j){
                i++;
            }
            if (i<j){
                swap1(arr,i,j);
            }
        }
        return i;
    }

?②把最右边的设置 为标志位,一个哨兵 从最左侧依次进行比较,把 数组 分为两个区,代码 如下:

public static void quickSort2(int[] arr,int l,int r){

        if ( l < r ){
            //随机产生标志位
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int q = partition2(arr,l,r);
            quickSort(arr,l,q-1);
            quickSort(arr,q+1,r);
        }
    }

public static int partition2(int[] arr,int l,int r){
        int i = l-1;
        int j = r;
        while (l < j){
            //每次把最右边的设置为标志位,这样减少了额外空间
            if (arr[l]<=arr[r]){
                i++;
                swap1(arr,i,l);
                l++;
            }else{
                j--;
                swap1(arr,j,l);
            }
        }
        swap1(arr,j,r);
        return i+1;
    }

?③把数组分为三部分,大于区,小于区和等于区,这样会减少比较的次数,代码如下:

public static void quickSort1(int[] arr,int l,int r){

        if ( l < r ){
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int[] q = partition1(arr,l,r);
            quickSort(arr,l,q[0]-1);
            quickSort(arr,q[0]+1,r);
        }
    }

 //划分数组的优化算法,把一个数组分为三个区,大于区,小于区和等于区
    public static int[] partition1(int[] arr,int l,int  r){
        int i = l-1;
        int j = r;
        while (l < j){
            //每次把最右边的设置为哨兵,这样减少了额外空间
            if (arr[l]<arr[r]){
                swap1(arr,++i,l++);
            }else if (arr[l]>arr[r]){
                swap1(arr,--j,l);
            }else {
                l++;
            }
        }
        swap1(arr,j,r);
        return new int[] {i+1,j};
    }

?完整代码如下:

package study.tao.sort;

import java.util.Arrays;

/**
 * Created by Taoyongpan on 2017/11/13.
 * 快速排序及其优化,我们一般快排的时候会把一个数组 分为两个区
 * 大于等于和小于两个区,现在我们要做的是讲一个数组分为三个区,大于,等于和小于三个区
 * 这样做的好处是每次把相等的数放在中间位置,这样会减少比较次数
 */
public class QuickSort {

    //随机产生一个数组 大小为maxSize,最大值为maxValue的数组
    public static int[] generateRandomArray(int maxSize,int maxValue){
        if (maxSize<=0){
            return null;
        }
        int[] arr = new int[(int)((maxSize+1)*Math.random())];

        for (int i = 0 ; i < arr.length ; i++){
            arr[i] = (int) ((maxValue+1)*Math.random());
        }
        return arr;
    }

    //数组的输出函数
    public static void printArray(int[] arr){
        if (arr==null){
            return;
        }
        for (int j = 0 ; j < arr.length ; j++){
            System.out.print(arr[j]+" ");
        }
        System.out.println();
    }

    //复制函数
    public static int[] copyArray(int[] arr){
        int[] res = new int[arr.length];
        if (arr == null){
            return null;
        }
        for (int i = 0 ; i < arr.length ; i++){
            res[i] = arr[i];
        }
        return res;
    }

    //交换函数
    //位运算进行交换
    public static void swap(int[] arr,int i,int j){
        arr[i] = arr[i]^arr[j];
        arr[j] = arr[i]^arr[j];
        arr[i] = arr[i]^arr[j];
    }
    //需要额外空间的交换函数
    public static void swap1(int[] arr,int i,int j){
        int temp;
        temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    //系统的比较函数
    public static void arraySort(int[] arr){
        Arrays.sort(arr);
    }

    //比较自己写的排序函数和系统的排序函数结果是否相等
    public static boolean isEqual(int[] arr1,int[] arr2){
        if ((arr1 == null && arr2 !=null)||(arr1 !=null && arr2 ==null)||( arr1 == null && arr2 == null)){
            return false;
        }
        if (arr1.length != arr2.length){
            return false;
        }
        for (int i = 0 ; i <arr1.length;i++){
            if (arr1[i] != arr2[i]){
                return false;
            }
        }
        return true;
    }
    //快速排序
    public static void quickSort(int[] arr,int l,int r){

        if ( l < r ){
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int q = partition(arr ,l , r);
            quickSort(arr,l,q-1);
            quickSort(arr,q+1,r);
        }
    }
    public static void quickSort1(int[] arr,int l,int r){

        if ( l < r ){
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int[] q = partition1(arr,l,r);
            quickSort(arr,l,q[0]-1);
            quickSort(arr,q[0]+1,r);
        }
    }
    public static void quickSort2(int[] arr,int l,int r){

        if ( l < r ){
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int q = partition2(arr,l,r);
            quickSort(arr,l,q-1);
            quickSort(arr,q+1,r);
        }
    }
    //定位函数
    //划分数组,用两个哨兵的方法
    public static int partition(int[] arr,int l,int r){
        int p = arr[l];//设置哨兵位置
        int i = l;
        int j = r;
        while (i < j){
            while (arr[j] >= p && i < j){
                j--;
            }
            if (i<j){
                swap1(arr,i,j);
            }
            while (arr[i] <= p && i < j){
                i++;
            }
            if (i<j){
                swap1(arr,i,j);
            }
        }
        return i;
    }
    //划分数组的优化算法,把一个数组分为三个区,大于区,小于区和等于区
    public static int[] partition1(int[] arr,int l,int  r){
        int i = l-1;
        int j = r;
        while (l < j){
            //每次把最右边的设置为哨兵,这样减少了额外空间
            if (arr[l]<arr[r]){
                swap1(arr,++i,l++);
            }else if (arr[l]>arr[r]){
                swap1(arr,--j,l);
            }else {
                l++;
            }
        }
        swap1(arr,j,r);
        return new int[] {i+1,j};
    }
    //划分数组的一级优化
    public static int partition2(int[] arr,int l,int r){
        int i = l-1;
        int j = r;
        while (l < j){
            //每次把最右边的设置为哨兵,这样减少了额外空间
            if (arr[l]<=arr[r]){
                i++;
                swap1(arr,i,l);
                l++;
            }else{
                j--;
                swap1(arr,j,l);
            }
        }
        swap1(arr,j,r);
        return i+1;
    }
    //主函数
    public static void main(String[] args){

        int maxSize = 100;
        int maxValue = 100;
        int maxTime = 3;
        boolean flag = true;
        int[] arr1 = generateRandomArray(maxSize,maxValue);//随机生成数组
        int[] arr2 = copyArray(arr1);//把数组1中的值复制到arr2中

        quickSort(arr1,0,arr1.length-1);
        arraySort(arr2);

        quickSort1(arr1,0,arr1.length-1);
        arraySort(arr2);

        quickSort2(arr1,0,arr1.length-1);
        arraySort(arr2);
        System.out.println(isEqual(arr1,arr2)?"succeed":"failed");
        printArray(arr1);
    }
}

?

上一篇: 图解58同城第三季度财报:营收稳步持续增长 下一篇: 没有下一篇了!
发表评论
用户名: 匿名