易解排序算法 - 空间换取时间(java写:基数排序,计数排序,桶排序,排序全部源代码)

排序算法之空间换取时间

    空间换取时间的算法在当下用来解决问题是很常见的,因为现在的硬件很发达,内存,CPU配置都非常高,遇到难解的问题用空间换取时间是值得的。那么在排序算法种,使用空间换取时间的算法有那些?

    1.计数排序:

        计数排序是一种牺牲了大量空间的排序算法,计数排序和序列中数据的值域有关系,值域越大,我们所开辟的空间就越大,而且计数排序局限于 0 - 无穷大 的整数。

        下图中数据的值域是 2 - 8 ,正常情况下我们只需要开辟9个数据位就够了,这里我们开辟了10个,为了图片显得整齐。

        计数排序的算法核心内容就是: 遍历一遍,用新数组记录自己下标对应的数据出现的次数。然后遍历标记数组输出对应的数值。

易解排序算法 - 空间换取时间(java写:基数排序,计数排序,桶排序,排序全部源代码)_第1张图片

源代码:

 

/**
     * 计数排序 area为域值,也就是数组中值的上界
     * 下届默认为0
     * 计数排序是以时间换取空间,申请一个阈值为上界大小的数组
     * @param array
     * @return
     */
    public static Integer[] calcuNumberOrder(Integer[] array,Integer area){
        Integer[] temp = new Integer[area+1];
        Integer dt = -1;
        for(Integer i = 0;i0){
                array[dt] = j;
                temp[j]--;
                dt++;
            }
        }
        return array;
    }

    2.基数排序

        基数排序和计数排序的理念是不同的,基数排序有十个桶,每一个桶所拥有的容量是未知的。基数排序是根据数据各个位上的数值进行整理排序,整理的次数和数据中最大值的位数有关系。

        基数排序的算法核心是:对数据的各个 “位” 进行归类,如下方五个两位数的集合,我们首先对各位进行归类,遍历数组把“个位”相同的数据插入到对应的桶里。都插好后,在从桶中拿出来挨个替换数组值,准备进行第二次整理。

        第二次整理“十位”,按照“十位”来归类整理,再从桶中读出来放入数组,此时数组已经有序。

        整理的次数和数组中最大值的“位”数相同。

易解排序算法 - 空间换取时间(java写:基数排序,计数排序,桶排序,排序全部源代码)_第2张图片

    /**
     * 基数排序
     * 按位归类放入桶中 然后再从桶中按 0 - 9编号的桶依次取出
     * 一共归类最大值的 位个数次,  也就是说 1000归类四次   100 归类三次  10 归类两次次
     * @param array
     * @param level
     * @return
     */
    public static Integer[] baseNumberOrder(Integer[] array,Integer level){
        Integer[][] box = new Integer[10][array.length];
        Integer nowbit = 10;        //取余位
        Integer nowbox = -1;        //向桶内插入数据的当前桶  取余被除计算后的值
        Integer countArray = 0;     //收取桶内的元素计数器
        Integer nowcut = 1;         //被除位
        int i = 0, j = 0;           //经常循环使用的迭代变量
        while (nowbit <= level) {
            for (i = 0; i < array.length; i++) {
                nowbox = (array[i]%nowbit)/nowcut;
                if (box[nowbox][0] == null)
                    box[nowbox][0] = 0;
                box[nowbox][0]++;
                box[nowbox][box[nowbox][0]] = array[i];
            }
            for (i = 0; i < box.length;i++){
                if (box[i][0] == null || box[i][0] == 0){
                    continue;
                }
                for (j = 1; j <= box[i][0] ; j++) {
                    array[countArray] = box[i][j];
                    countArray++;
                }
                box[i][0] = 0;
            }
            countArray = 0;
            nowbit *= 10;
            nowcut = nowbit / 10;
        }
        return array;
    }


    3.桶排序

        桶排序和上面的两个算法也不相同,桶排序我们可以自由的规定桶的数量,桶排序的快慢和桶的数量有绝对的关系。既不能使桶数超过数据量,也不能设置的太小。太大过于浪费,太小又失去了性能,所以这个值是要根据数据量来,个人觉得桶应该在数据量的1/3到1/4之间为好。

        桶排序的概念是,根据值域和桶数划分出每个桶所装的值的范围,然后我们遍历待排序数组,把值插入对应范围的桶,插入时我们按序插入,保证每个桶是有序的。都插入完毕再读出来替换原数组值。

        图解:

        易解排序算法 - 空间换取时间(java写:基数排序,计数排序,桶排序,排序全部源代码)_第3张图片

    /**
     * 桶排序,参数为数组,值域,桶个数
     * @param array
     * @param area
     * @param bucketNum
     * @return
     */
    public static Integer[] bucketOrder(Integer[] array,Integer area,Integer bucketNum){
        if (bucketNum<1) return null;
        Bucket[] buckets = new Bucket[bucketNum];
        Integer bucketArea = area / bucketNum;
        Integer bucketIndex = 0;
        Bucket temp = null;
        Bucket comp = null;
        int i = 0;
        for(i = 0; i < array.length ; i++){
            bucketIndex = array[i] / bucketArea;
            if(buckets[bucketIndex] == null){
                buckets[bucketIndex] = new Bucket(0);
            }
            temp = new Bucket(array[i]);            //插入桶
            comp = buckets[bucketIndex].next;
            while (comp != null){
                if(temp.data < comp.data){
                    comp.pre.next = temp;
                    temp.pre = comp.pre;
                    temp.next = comp;
                    comp.pre = temp;
                    break;
                }else if (comp.next == null) {
                    comp.next = temp;
                    temp.pre = comp;
                    break;
                }
                comp = comp.next;
            }
            if (comp == null) {
                buckets[bucketIndex].next = temp;
                temp.pre = buckets[bucketIndex];
            }
        }
        comp = null;                       //再次使comp指向空处
        bucketIndex = 0;                        //当作array下标表示器
        for(i = 0;i < buckets.length ;i++){
            if (buckets[i] == null){
                continue;
            }
            comp = buckets[i].next;
            if (comp == null){
                continue;
            }
            while (comp != null){
                array[bucketIndex] = comp.data;
                bucketIndex++;
                comp = comp.next;
            }
        }
        return array;
    }

总结:上述三个算法都是牺牲了时间而换取空间,但各个又有其所用之处。
       比如计数排序:计数排序要申请数据值域那么大的空间,不能为小数或负数,那么数据量少,值域很大的数据显然不适合这种排序算法,那么我们计数排序适合值域小,都为整数,而数据量特别大的数据。
       再看基数排序:基数排序是通过计算,按位划分数据,然后整理。整理次数和数据最大值的位数相关。基数排序省去了一些空间,但是增加了很多计算的操作。数据也必须是整数。基数排序应用在数据量不是特别大,而且整理次数不是很多的情况。
       再看桶排序,桶排序绝对和桶的数量有关系了,一般情况下桶排序是最常用的,这个理念不需要对数据有要求,因为桶存的是一个范围,本身有加上了插入排序,所以弊端也是桶数量不能太少,太少会使得时间浪费在遍历链表上。所以桶唯一的限制就是数据最好是相对均匀,桶的数量最好是1/3 - 1/4之间使得既不消耗大量的空间,而且又相对快捷。                   


最后

公布全部的排序算法源代码

排序算法测试程序

算法程序

package com.cccl.algorithm.order;

import java.util.Calendar;
import java.util.Date;
import java.util.Random;


/**
 * Created by ChinaLee on 2018/3/15.
 */
public class Order {

    public  static Calendar calendar = Calendar.getInstance();  //计算排序时间

    /**
     * 起泡排序,返回一个排好序的数组
     *   i  i+1
     *   7  16   9  11  16  18    7 - 16 不换
     *       i  i+1
     *   7  16   9  11  16  18    16 - 9  换
     *           i  i+1
     *   7  9   16  11  16  18     16 - 11 换
     *               i  i+1
     *   7  9   11  16  16  18      16 - 16 不换
     *   ------------------------------ 准备从7执行下一个起泡的循环
     *   7  9   11  16  16  18
     * @param array
     * @return
     */
    public static Integer[] bubbleOrder(Integer[] array){
        for(Integer i = 0;i array[j + 1]) {
                    Integer temp = array[j + 1];
                    array[j + 1] = array[j];
                    array[j] = temp;
                }
            }
        }
        return array;
    }

    /**
     * 插入排序,返回一个排序好的数组
     *              提出key = array[i] = 13
     *           j   i       j与key比较 j大把j给j+1然后j--
     *   7  16  18  13  11  8  2  16  1
     *       j       i       j再与key比较  j大把j给j+1然后j--
     *   7  16  18  18  11  8  2  16  1
     *   j           i       j再与key比较  key大跳出循环  把key给j+1 然后插入成功
     *   7  16  16  18  11  8  2  16  1
     *   ----------------i------------- 准备执行下一个i 的插入
     *   7  13  16  18  11  8  2  16  1
     * @param array
     * @return
     */
    public static Integer[] insertOrder(Integer[] array){
        Integer key = 0;
        for(int i = 1 ; i= 0 && array[j] > key ) ; j--){
                array[j+1] = array[j];
            }
            array[j+1] = key;
        }
        return array;
    }

    /**
     * 选择排序,找到最小的,记录下标
     * index = i        //index记录最小的下标
     *     j         如果array[j]小于array[index] 那么就用index记录最小的下标  index = 1
     * (3) 2 7 6 8 9
     *         j        //7大不记录
     * 3 (2) 7 6 8 9
     *      知道j走完了 有小的就用index记录下标
     * 3 (2) 7 6 8 9
     *          最后把array[index]和array{i}换位置
     * (2) 3 7 6 8 9
     * @param array
     * @return
     */
    public static Integer[] selectOrder(Integer[] array){
        Integer index,temp;
        Integer time = array.length - 1;
        for(int i = 0 ; i < time ; i++){
            index = i;
            for(int j = i+1;j array[j]){
                    index = j;
                }
            }
            temp = array[index];
            array[index] = array[i];
            array[i] = temp;
            index++;
        }
        return array;
    }


    /**
     * 希尔排序
     * @param array
     * @param addNum
     * @return
     */
    public static Integer[] shellOrder(Integer[] array,Integer addNum){
        Integer temp;
        Integer gap = 1;
        while(gap < array.length/addNum) {
            gap =gap*addNum+1;
        }
        while (gap> 0){   // 荡循环,维护gap
            for (Integer i = gap; i < array.length; i++) {  //因gap位之前的元素都是每个组的第一位
                temp = array[i];                            // 从gap位开始 那么我们就从gap位开始对个元素做插入排序
                Integer j;                                  // 可能会问 每个元素所在的组不一样,怎么就插入了
                for (j = i-gap; j >= 0 && array[j]> temp; j-=gap) { //正是因为每个元素所在的组不一样  那么我们在对每个元素做插入排序的时候
                    array[j+gap] = array[j];                        //遍历的都是相隔gap位的元素,所以相隔gap位的元素都是一组的
                }                                                   //做插入排序
                array[j+gap] = temp;
            }
            gap = (int)Math.floor(gap/addNum);
        }
        return array;
    }

    /**
     * 归并排序入口
     * 不需要设置其边界值的入口
     * @param array
     * @return
     */
    public static Integer[] defaultRecursionMergeOrder(Integer[] array){
        if (array != null)
            array = Order.recursionMergeOrder(array,0,array.length-1);
        return array;
    }

    /**
     * 归并排序
     * 传入待排序数组,以及待排序的左边界和右边界
     * @param array
     * @param left
     * @param right
     * @return
     */
    public static Integer[] recursionMergeOrder(Integer[] array,Integer left,Integer right){
        if(left == right) {  //如果数组左边界和右边界相同的话就不用继续递归归并了 并返回这个唯一的一个元素的数组
            return new Integer[]{ array[right] };
        }
        Integer mid = (right + left) / 2;       //如果还可以二分归并那么算出中间值
        Integer[] lArray = Order.recursionMergeOrder(array,left,mid);  //左的给左  右的给右依次递归
        Integer[] rArray = Order.recursionMergeOrder(array,mid+1,right);
        return leftMergeRight(lArray,rArray); //合并俩数组的值
    }

    /**
     * 归并排序:和并两个有序数组
     * @param leftArray
     * @param rightArray
     * @return
     */
    public static Integer[] leftMergeRight(Integer[] leftArray,Integer[] rightArray){
        Integer newLength = leftArray.length + rightArray.length;
        Integer[] newArray = new Integer[newLength];    //申请一个长度为左右数组长度之和的新数组
        Integer point = 0,leftPoint = 0,rightPoint = 0;  //数组元素比较和记录指针

        while (leftPoint < leftArray.length && rightPoint < rightArray.length) {

            //两个引用分别指向两个数组  从0开始比较大的计入新数组中  新数组指针 比较者大的数组指针+1
            newArray[point++] = leftArray[leftPoint] < rightArray[rightPoint] ? leftArray[leftPoint++] : rightArray[rightPoint++];

        }
        //一旦左右数组有一个指针不能继续比较了,那么就对剩下的单个数组进行合并
        while (leftPoint < leftArray.length) {  //左面数组没合并玩 依次合并入新数组

            newArray[point++] = leftArray[leftPoint++];
        }
        while (rightPoint < rightArray.length) { //右边数组没合并完 依次合并入新数组

            newArray[point++] = rightArray[rightPoint++];
        }
        return newArray;
    }


    /**
     * 循环实现归并排序  不会
     */

    /**
     * 快速排序入口
     * @param array
     * @return
     */
    public static Integer[] defaultQuictSortOrder(Integer[] array){
        if (array != null)
            quictSortOrder(array,0,array.length-1);
        return array;
    }

    /**
     * 快速排序
     * 传入参数  数组  待排序起点的下标,待排序数组终点的下标
     * @param array
     * @param pre
     * @param rear
     * @return
     */
    public static Integer[] quictSortOrder(Integer[] array,Integer pre,Integer rear){
        Integer midNumber; //记录分为两部分后的中间值    主元所在位置
        if (pre < rear){ //如果pre < rear  开始下标小于终点下标
            midNumber = quictSortPartition(array,pre,rear); // 返回主元所在位置并把元素分布在主元的左右两边
            Order.quictSortOrder(array,pre,midNumber-1); //继续对主元左边进行快速排序
            Order.quictSortOrder(array,midNumber+1,rear);//继续对住主元右边进行快速排序
        }
        return array;
    }

    /**
     * 设定当前部分数组末尾元素为主元
     * 把数组元素分布再主元左右两边
     * 返回主元所在的位置
     * @param array
     * @param pre
     * @param rear
     * @return
     */
    public static Integer quictSortPartition(Integer[] array,Integer pre,Integer rear){
        Integer mianNumber = array[rear]; // 记录主元的值   设定以数组末尾元素为主元
        Integer index = pre - 1;          //使用index变量为记录第一个大于主元的元素的前一个位置
        Integer temp;  //temp用来交换值
        for (Integer j = pre; j < rear ; j++){//数组从 pre 遍历到 (rear-1)
            if(array[j] <= mianNumber){  //如果array[j]小于主元
                index += 1;              //我们使 index前进一位
                temp = array[index];     //交换array[index]和array[j]
                array[index] = array[j];  //描述 : 为什么这样做   首先如果index和j表示的是同一位元素,那么其实没必要交换其值,但是
                array[j] = temp;//可能你会问,没必要交换为什么交换。答:这是对算法的一种妥协    举例来看
            }
        }
        /**
         * 如果 20 21 22 23 50 24 55 18 30
         * 首先以最后一位 30 为主元
         * index为-1   pre 为0   rear 为10
         * 咱们按照程序流程来走,
         * 20小于主元30  index为0  交换 array[index] 和array[j]  index和j都为0
         * 直到j == 3  也就是遍历到23  index == 3都是相同位置的元素自己和自己交换
         * 但是当j走到4,也就是遍历到50
         * 50大于主元30 重新执行下一个循环 当前index == 3
         * j走到了5 也就是遍历到24 index+1变成了4 index变成了标记大于主元值的位置
         * 这时我们交换的是 50 和 24
         * 数组变成 20 21 22 23 24 (50) 55 18 30
         * J继续向下遍历  此时遍历到55  55大于主元30 那么重新执行循环 当前index为4也就是50的前一个位置
         * j遍历到 18  小于主元30   index+1变成了5标记到大于主元的位置,交换50和18
         * 数组变成 20 21 22 23 24 18 55 (50) 30  当前index==5标记的是18的下标
         * j=rear遍历结束
         * 此时18左边全是小于主元的,我们使index++  变成 6 ,让第6位也就是第一个大于主元的值的元素和主元交换,30和55换
         * 数组变成 20 21 22 23 24 18 30 55 50 此时index标记的是30的位置
         * 返回 主元下标的位置 index
         */
        index++;
        temp = array[index];
        array[index] = array[rear];
        array[rear] = temp;
        return index;
    }

    /**
     * 堆排序入口,需要传入一个长度大于等于2的数组
     * 如果小于2就别排序了,没啥用也
     * @param array
     * @return
     */
    public static Integer[] defaultHeapSort(Integer[] array){
        if (array.length<2){
            System.out.println("提示:数组长度小于2,由于我们使用1 - n的下标,不使用0 。");
            System.out.println("提示:所以一个元素进来一个元素出去我们就别脱裤子放屁了。");
            System.out.println("提示:将返回空值,恶心你一下!");
            return null;
        }
        Order.heapSort(array);
        return array;
    }

    /**
     * 堆排序
     * 构建初始堆
     * 替换第一和最后的元素,堆长-1
     * 维护堆顶元素和堆的性质
     * @param array
     * @return
     */
    public static Integer[] heapSort(Integer[] array){
        Integer heapSize = array.length -1;
        Integer temp = null;
        Order.createMaxHeap(array,heapSize);
        for(Integer i = array.length-1 ; i > 1 ; i--){
            temp = array[1];
            array[1] = array[i];
            array[i] = temp;
            heapSize = heapSize - 1;
            maintainHeapSort(array,1,heapSize);
        }
        return array;
    }

    /**
     * 创建初始堆即从最后一个根结点向前遍历
     * @param array
     * @param heapSize
     */
    public static void createMaxHeap(Integer[] array,Integer heapSize){
        for(Integer i = heapSize / 2 ; i >0 ; i--){
            Order.maintainHeapSort(array,i,heapSize);
        }
    }

    /**
     * 维护堆的性质,当前为大顶堆,也就是说左右孩子必须小于根。
     * 如果左右孩子不小于根,替换根和左右孩子中大的结点,并对该结点向下继续维护堆性质
     *  如果左右孩子都小于根那么就不用继续向下维护
     * @param array
     * @param index
     * @param heapSize
     */
    public static void maintainHeapSort(Integer[] array,Integer index,Integer heapSize){
        Integer lChild = Order.leftChild(index);
        Integer rChild = Order.rightChild(index);
        Integer largest = null;
        Integer temp = null;
        if ( lChild <= heapSize && array[lChild] > array[index]){
            largest = lChild;
        }else{
            largest = index;
        }
        if(rChild <= heapSize && array[rChild] > array[largest]){
            largest = rChild;
        }
        if (largest != index){
            temp = array[largest];
            array[largest] = array[index];
            array[index] = temp;
            maintainHeapSort(array,largest,heapSize);
        }
    }

    /**
     * 返回标号为index的结点的左孩子的下标
     * @param index
     * @return
     */
    private static Integer leftChild(Integer index){
        return (index * 2);
    }

    /**
     * 返回标号为index的结点的右孩子的下标
     * @param index
     * @return
     */
    private static Integer rightChild(Integer index){
        return ((index * 2) + 1);
    }

    /**
     * 返回标号为index的结点的父结点的下标
     * @param index
     * @return
     */
    private static Integer parent(Integer index){
        return index / 2;
    }


    /**
     * 计数排序 area为域值,也就是数组中值的上界
     * 下届默认为0
     * 计数排序是以时间换取空间,申请一个阈值为上界大小的数组
     * @param array
     * @return
     */
    public static Integer[] calcuNumberOrder(Integer[] array,Integer area){
        Integer[] temp = new Integer[area+1];
        Integer dt = -1;
        for(Integer i = 0;i0){
                array[dt] = j;
                temp[j]--;
                dt++;
            }
        }
        return array;
    }


    /**
     * 基数排序
     * 按位归类放入桶中 然后再从桶中按 0 - 9编号的桶依次取出
     * 一共归类最大值的 位个数次,  也就是说 1000归类四次   100 归类三次  10 归类两次次
     * @param array
     * @param level
     * @return
     */
    public static Integer[] baseNumberOrder(Integer[] array,Integer level){
        Integer[][] box = new Integer[10][array.length];
        Integer nowbit = 10;        //取余位
        Integer nowbox = -1;        //向桶内插入数据的当前桶  取余被除计算后的值
        Integer countArray = 0;     //收取桶内的元素计数器
        Integer nowcut = 1;         //被除位
        int i = 0, j = 0;           //经常循环使用的迭代变量
        while (nowbit <= level) {
            for (i = 0; i < array.length; i++) {
                nowbox = (array[i]%nowbit)/nowcut;
                if (box[nowbox][0] == null)
                    box[nowbox][0] = 0;
                box[nowbox][0]++;
                box[nowbox][box[nowbox][0]] = array[i];
            }
            for (i = 0; i < box.length;i++){
                if (box[i][0] == null || box[i][0] == 0){
                    continue;
                }
                for (j = 1; j <= box[i][0] ; j++) {
                    array[countArray] = box[i][j];
                    countArray++;
                }
                box[i][0] = 0;
            }
            countArray = 0;
            nowbit *= 10;
            nowcut = nowbit / 10;
        }
        return array;
    }


    /**
     * 桶排序,参数为数组,值域,桶个数
     * @param array
     * @param area
     * @param bucketNum
     * @return
     */
    public static Integer[] bucketOrder(Integer[] array,Integer area,Integer bucketNum){
        if (bucketNum<1) return null;
        Bucket[] buckets = new Bucket[bucketNum];
        Integer bucketArea = area / bucketNum;
        Integer bucketIndex = 0;
        Bucket temp = null;
        Bucket comp = null;
        int i = 0;
        for(i = 0; i < array.length ; i++){
            bucketIndex = array[i] / bucketArea;
            if(buckets[bucketIndex] == null){
                buckets[bucketIndex] = new Bucket(0);
            }
            temp = new Bucket(array[i]);            //插入桶
            comp = buckets[bucketIndex].next;
            while (comp != null){
                if(temp.data < comp.data){
                    comp.pre.next = temp;
                    temp.pre = comp.pre;
                    temp.next = comp;
                    comp.pre = temp;
                    break;
                }else if (comp.next == null) {
                    comp.next = temp;
                    temp.pre = comp;
                    break;
                }
                comp = comp.next;
            }
            if (comp == null) {
                buckets[bucketIndex].next = temp;
                temp.pre = buckets[bucketIndex];
            }
        }
        comp = null;                       //再次使comp指向空处
        bucketIndex = 0;                        //当作array下标表示器
        for(i = 0;i < buckets.length ;i++){
            if (buckets[i] == null){
                continue;
            }
            comp = buckets[i].next;
            if (comp == null){
                continue;
            }
            while (comp != null){
                array[bucketIndex] = comp.data;
                bucketIndex++;
                comp = comp.next;
            }
        }
        return array;
    }

    /**
     * 桶的数据结构
     */
    private static class Bucket{
        public Bucket pre = null;
        public Bucket next = null;
        public Integer data = 0;
        public Bucket(Integer data){
            this.data = data;
        }
    }



    /**
     * 方法用于输出array的元素值。
     * @param array
     * @return
     */
    public static boolean showArray(Integer[] array){
        try {
            if (array == null){
                System.out.println("提示:数组为空,将不进行输出!");
                return false;
            }
            for (Integer i : array) {
                System.out.print(" " + i + " ");
            }
            System.out.println();
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 方法用于输出堆排序的array的元素值。
     * 由于堆排序使用下标为1-0  所以对于下标为0的元素我们不予以排序
     * 也就不需要输出其值
     * @param array
     * @return
     */
    public static boolean showHeapSortArray(Integer[] array){
        try {
            if (array.length < 2){
                System.out.println("提示:数组只有一个元素还玩什么堆排序,不进行输出!");
                return false;
            }
            for (Integer i = 1 ; i 

测试程序

package com.cccl.algorithm.order;

import java.util.Date;

/**
 * Created by 小H on 2018/3/15.
 */
public class TestOrder {




    public static void main(String[] args){
        Integer arrayRange = 100000000;
        Integer arrayLength = 10000000;
        System.out.println();
        //TestBubbleOrder(arrayLength,arrayRange);
        //TestInsertOrder(arrayLength,arrayRange);
        //TestSelectOrder(arrayLength,arrayRange);
        //TestShellOrder(arrayLength,arrayRange,10);
        //TestBackAndOrder(arrayLength,arrayRange);
        //TestHeapSortOrder(arrayLength,arrayRange);
        //TestQuickSortOrder(arrayLength,arrayRange);
        TestCalcuNumberOrder(arrayLength,arrayRange);
        TestBaseNumberOrder(arrayLength,arrayRange);
        TestBuckerOrder(arrayLength,arrayRange,1000000);
    }

    /**
     * 测试起泡排序
     */
    public static void TestBubbleOrder(Integer arrayLength,Integer arrayRange){
        Integer[] array = Order.createRandomArray(arrayLength,arrayRange);
        Long begin = Order.getMillis(new Date());
        array = Order.bubbleOrder(array);
        Long end = Order.getMillis(new Date());
        System.out.println("冒泡排序:" + arrayLength + "条数据,耗时 " + (end - begin) + "毫秒!");
        //Order.showArray(array);
    }

    /**
     * 测试插入排序
     */
    public static void TestInsertOrder(Integer arrayLength,Integer arrayRange){
        Integer[] array = Order.createRandomArray(arrayLength,arrayRange);
        Long begin = Order.getMillis(new Date());
        array = Order.insertOrder(array);
        Long end = Order.getMillis(new Date());
        System.out.println("插入排序:" + arrayLength + "条数据,耗时 " + (end - begin) + "毫秒!");
        //Order.showArray(array);
    }

    /**
     * 测试选择排序
     */
    public static void TestSelectOrder(Integer arrayLength,Integer arrayRange){
        Integer[] array = Order.createRandomArray(arrayLength,arrayRange);
        Long begin = Order.getMillis(new Date());
        array = Order.selectOrder(array);
        Long end = Order.getMillis(new Date());
        System.out.println("选择排序:" + arrayLength + "条数据,耗时 " + (end - begin) + "毫秒!");
        //Order.showArray(array);
    }

    /**
     * 测试希尔排序
     */
    public static void TestShellOrder(Integer arrayLength,Integer arrayRange,Integer shell){
        Integer[] array = Order.createRandomArray(arrayLength,arrayRange);
        Long begin = Order.getMillis(new Date());
        array = Order.shellOrder(array,shell);
        Long end = Order.getMillis(new Date());
        System.out.println("希尔排序:" + arrayLength + "条数据,耗时 " + (end - begin) + "毫秒!");
       // Order.showArray(array);
    }

    /**
     * 测试归并排序
     */
    public static void TestBackAndOrder(Integer arrayLength,Integer arrayRange){
        Integer[] array = Order.createRandomArray(arrayLength,arrayRange);
        Long begin = Order.getMillis(new Date());
        array = Order.defaultRecursionMergeOrder(array);
        Long end = Order.getMillis(new Date());
        System.out.println("归并排序:" + arrayLength + "条数据,耗时 " + (end - begin) + "毫秒!");
        //Order.showArray(array);
    }

    /**
     * 测试快速排序
     */
    public static void TestQuickSortOrder(Integer arrayLength,Integer arrayRange){
        Integer[] array = Order.createRandomArray(arrayLength,arrayRange);
        Long begin = Order.getMillis(new Date());
        array = Order.defaultQuictSortOrder(array);
        Long end = Order.getMillis(new Date());
        System.out.println("快速排序:" + arrayLength + "条数据,耗时 " + (end - begin) + "毫秒!");
        //Order.showArray(array);
    }

    /**
     * 测试堆排序
     */
    public static void TestHeapSortOrder(Integer arrayLength,Integer arrayRange){
        Integer[] array = Order.createRandomArray(arrayLength,arrayRange);
        Long begin = Order.getMillis(new Date());
        array = Order.defaultHeapSort(array);
        Long end = Order.getMillis(new Date());
        System.out.println("堆排序:" + arrayLength + "条数据,耗时 " + (end - begin) + "毫秒!");
        //Order.showHeapSortArray(array);
    }
    /**
     * 测试计数排序
     */
    public static void TestCalcuNumberOrder(Integer arrayLength,Integer arrayRange){
        Integer[] array = Order.createRandomArray(arrayLength,arrayRange);
        Long begin = Order.getMillis(new Date());
        array = Order.calcuNumberOrder(array,arrayRange);
        Long end = Order.getMillis(new Date());
        System.out.println("计数排序:" + arrayLength + "条数据,耗时 " + (end - begin) + "毫秒!");
        //Order.showArray(array);
    }

    /**
     * 测试基数排序
     */
    public static void TestBaseNumberOrder(Integer arrayLength,Integer arrayRange){
        Integer[] array = Order.createRandomArray(arrayLength,arrayRange);
        Long begin = Order.getMillis(new Date());
        array = Order.baseNumberOrder(array,arrayRange);
        Long end = Order.getMillis(new Date());
        System.out.println("基数排序:" + arrayLength + "条数据,耗时 " + (end - begin) + "毫秒!");
        //Order.showArray(array);
    }

    /**
     * 测试桶排序
     */
    public static void TestBuckerOrder(Integer arrayLength,Integer arrayRange,Integer buckerNum){
        Integer[] array = Order.createRandomArray(arrayLength,arrayRange);
        Long begin = Order.getMillis(new Date());
        array = Order.bucketOrder(array,arrayRange,buckerNum);
        Long end = Order.getMillis(new Date());
        System.out.println("桶排序:" + arrayLength + "条数据,耗时 " + (end - begin) + "毫秒!");
        //Order.showArray(array);
    }
}

你可能感兴趣的:(算法)