算法(一)---排序算法

(1)直接插入排序

基本介绍

直接插入排序是将一个待排序的记录,插入到前面已经排好序的有序序列中去,如此反复循环,直到全部排好顺序为止。
在这里插入图片描述

单个排序

    //第一轮排序
    public static void sort01(int arr[]){
        // 先把下标为1的值作为待插入值
        int insertVal=arr[1];//下标为1的值
        //待插入值前面的值为被比较值
        int insertIndex=1-1;//下标为1的值的前面,前面值下标为0

        //给insertVal找到插入的位置
        //要插入的值,从下标为0的数开始比,如果比前面的数小,说明待插入的数还没有找到位置
        while (insertIndex >= 0 && insertVal <= arr[insertIndex]){
            arr[insertIndex+1]=arr[insertIndex];//把值后移以为,让出空间让待插入值插入
            insertIndex--;//insertIndex自减,就是接着往前面比较的意思
        }
        arr[insertIndex+1]=insertVal;//前面insertIndex已经减一了,这里加一,就等同于原来的arr[insertIndex]位置

    }

    //第二轮排序
    public static void sort02(int arr[]){
        int insertVal=arr[2];
        int insertIndex=2-1;
        while (insertIndex>=0 && insertVal<=arr[insertIndex]){
            arr[insertIndex+1]=arr[insertIndex];
            insertIndex--;
        }
        arr[insertIndex+1]=insertVal;
    }

    //第三轮排序
    public static void sort03(int arr[]){
        int insertVal=arr[3];
        int insertIndex=3-1;
        while (insertIndex>=0 && insertVal<=arr[insertIndex]){
            arr[insertIndex+1]=arr[insertIndex];
            insertIndex--;
        }
        arr[insertIndex+1]=insertVal;
    }

整合排序

    public static void sort(int arr[]){

        for (int i = 1; i < arr.length; i++) {
            // 先把下标为1的值作为待插入值
            int insertVal=arr[i];//下标为1的值
            //待插入值前面的值为被比较值
            int insertIndex=i-1;//下标为1的值的前面,前面值下标为0

            //给insertVal找到插入的位置
            //要插入的值,从下标为0的数开始比,如果比前面的数小,说明待插入的数还没有找到位置
            while (insertIndex >= 0 && insertVal <= arr[insertIndex]){
                arr[insertIndex+1]=arr[insertIndex];//把值后移以为,让出空间让待插入值插入
                insertIndex--;//insertIndex自减,就是接着往前面比较的意思
            }
            arr[insertIndex+1]=insertVal;//前面insertIndex已经减一了,这里加一,就等同于原来的arr[insertIndex]位置

        }
    }

进阶排序

    public static void sort(int arr[]){

        for (int i = 1; i < arr.length; i++) {
            // 先把下标为1的值作为待插入值
            int insertVal=arr[i];//下标为1的值
            //待插入值前面的值为被比较值
            int insertIndex=i-1;//下标为1的值的前面,前面值下标为0

            //给insertVal找到插入的位置
            //要插入的值,从下标为0的数开始比,如果比前面的数小,说明待插入的数还没有找到位置
            while (insertIndex >= 0 && insertVal <= arr[insertIndex]){
                arr[insertIndex+1]=arr[insertIndex];//把值后移以为,让出空间让待插入值插入
                insertIndex--;//insertIndex自减,就是接着往前面比较的意思
            }

            //加一句判断,是否需要交换位置
            if (insertIndex+1!=i){
                arr[insertIndex+1]=insertVal;
            }

            arr[insertIndex+1]=insertVal;//前面insertIndex已经减一了,这里加一,就等同于原来的arr[insertIndex]位置
            System.out.println("第"+i+"轮排序后的数组:"+ Arrays.toString(arr));

        }

    }

测试时间

80000个数据的数组,排序时间为2s

(2)希尔排序

基本介绍

在要排序的一组数中,根据某一增量分为若干子序列,并对子序列分别进行插入排序。然后逐渐将增量减小,并重复上述过程。直至增量为1,此时数据序列基本有序,最后进行插入排序。

单个排序

    //希尔排序第一轮排序
    public static void shellSort01(int arr[]){
        int temp=0;
        //把10个数分成5组
        for (int i = 5; i < arr.length; i++) {
            //遍历各组中所有的元素(共5组,每组有2个)步长5
            for (int j = i-5; j >= 0; j-=5) {
                //如果当前元素大于加上步长后的那个元素,说明交换
                if (arr[j]>arr[j+5]){
                    temp=arr[j];
                    arr[j]=arr[j+5];
                    arr[j+5]=temp;
                }
            }
        }
        System.out.println("希尔排序第一轮的结果"+ Arrays.toString(arr));
    }

    //希尔排序第二轮排序
    public static void shellSort02(int arr[]){
        int temp=0;
        //把10个数分成5组
        for (int i = 2; i < arr.length; i++) {
            //遍历各组中所有的元素(共5组,每组有2个)步长5
            for (int j = i-2; j >= 0; j-=2) {
                //如果当前元素大于加上步长后的那个元素,说明交换
                if (arr[j]>arr[j+2]){
                    temp=arr[j];
                    arr[j]=arr[j+2];
                    arr[j+2]=temp;
                }
            }
        }
        System.out.println("希尔排序第二轮的结果"+ Arrays.toString(arr));
    }

    //希尔排序第三轮排序
    public static void shellSort03(int arr[]){
        int temp=0;
        //把10个数分成5组
        for (int i = 1; i < arr.length; i++) {
            //遍历各组中所有的元素(共5组,每组有2个)步长5
            for (int j = i-1; j >= 0; j-=1) {
                //如果当前元素大于加上步长后的那个元素,说明交换
                if (arr[j]>arr[j+1]){
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
        }
        System.out.println("希尔排序第三轮的结果"+ Arrays.toString(arr));
    }

整合排序

    //希尔排序交换法,效率较低,不如使用位移法速度快
    public static void shellSort(int arr[]){
        int temp=0;
        //gap为步长,就是两个数之间的距离
        for(int gap=arr.length/2; gap>0; gap/=2){
            for (int i = gap; i < arr.length; i++) {
                //遍历各组中所有的元素(共5组,每组有2个)步长5
                for (int j = i-gap; j >= 0; j-=gap) {
                    //如果当前元素大于加上步长后的那个元素,说明交换
                    if (arr[j]>arr[j+gap]){
                        temp=arr[j];
                        arr[j]=arr[j+gap];
                        arr[j+gap]=temp;
                    }
                }
            }
            // System.out.println("希尔排序一轮的结果"+ Arrays.toString(arr));
        }
    }

测试时间

80000个数据的数组,排序耗时10s

(3)冒泡排序

基本介绍

冒泡排序是对相邻的元素进行两两比较,较大的数下沉,较小的数上浮,最终达到有序
在这里插入图片描述

单个排序

    //第一趟排序
    public static void sort01(int arr[]){
        int temp=0;//临时变量,用来交换位置
        for (int i = 0; i < arr.length-1; i++) {
            if (arr[i]>arr[i+1]){
                temp=arr[i+1];
                arr[i+1]=arr[i];
                arr[i]=temp;
            }
        }
    }

    //第二趟排序
    public static void sort02(int arr[]){
        int temp=0;//临时变量,用来交换位置
        for (int i = 0; i < arr.length-2; i++) {
            if (arr[i]>arr[i+1]){
                temp=arr[i+1];
                arr[i+1]=arr[i];
                arr[i]=temp;
            }
        }
    }

    //第三趟排序
    public static void sort03(int arr[]){
        int temp=0;//临时变量,用来交换位置
        for (int i = 0; i < arr.length-3; i++) {
            if (arr[i]>arr[i+1]){
                temp=arr[i+1];
                arr[i+1]=arr[i];
                arr[i]=temp;
            }
        }
    }

    //第四趟排序
    //可以看出来,数组长度为5,用了4次排序
    public static void sort04(int arr[]){
        int temp=0;//临时变量,用来交换位置
        for (int i = 0; i < arr.length-4; i++) {
            if (arr[i]>arr[i+1]){
                temp=arr[i+1];
                arr[i+1]=arr[i];
                arr[i]=temp;
            }
        }
    }

整合排序

    public static void sort(int arr[]){
        int temp=0;//临时变量,用来交换位置
        for (int j = 1; j < arr.length-1; j++) {
            for (int i = 0; i < arr.length-j; i++) {
                if (arr[i]>arr[i+1]){
                    temp=arr[i+1];
                    arr[i+1]=arr[i];
                    arr[i]=temp;
                }
            }
        }
    }

进阶排序

    public static void sortUpadte(int arr[]){
        int temp=0;//临时变量,用来交换位置
        boolean flag=false;//标识变量,表示是否进行过交换
        for (int j = 1; j < arr.length-1; j++) {
            for (int i = 0; i < arr.length-j; i++) {
                if (arr[i]>arr[i+1]){
                    flag=true;

                    temp=arr[i+1];
                    arr[i+1]=arr[i];
                    arr[i]=temp;
                }
            }
            System.out.println("第"+j+"趟排序后的数组:"+ Arrays.toString(arr));

            if (!flag){
                break;//在一趟排序中,不存在前面数比后面大,一次交换都没有发生过,就直接结束
            }else {
                flag=false;//重置flag,进行下一次判断
            }
        }
    }

测试时间

80000个数的数组,排序时间为14s

(4)快速排序

基本介绍

先从数列中取出一个数作为key值;将比这个数小的数全部放在它的左边,大于或等于它的数全部放在它的右边;对左右两个小数列重复第二步,直至各区间只有1个数。

在这里插入图片描述

代码示例

    public static void sort(int arr[], int left, int right){
        int temp=0;
        int l=left;//左下标
        int r=right;//右下标
        //中间轴
        int pivot=arr[(left+right)/2];

        //while循环的目的是让比pivot值小的放到左边,值大的放到右边
        while (l<r){
            //在pivot的左边一直找,找到大于等于pivot的值,才退出
            while (arr[l]<pivot){
                l+=1;
            }
            //在pivot的右边一直找,找到小于等于pivot的值,才退出
            while (arr[r]>pivot){
                r-=1;
            }
            //如果l>=r说明pivot的左右两边值,已经按照左边全部小于pivot,右边全部大于pivot
            if (l>=r){
                break;
            }

            //交换左右位置
            temp=arr[l];
            arr[l]=arr[r];
            arr[r]=temp;

            //如果交换之后,发现这个arr[l]==pivot。等于r--,前移
            if (arr[l]==pivot){
                r-=1;
            }

            //如果交换之后,发现这个arr[r]==pivot。等于l++,后移
            if (arr[r]==pivot){
                l+=1;
            }
        }

        //如果l==r,必须l++,r--,否则出现栈溢出
        if(l==r){
            l+=1;
            r-=1;
        }
        //向左递归
        if (left<r){
            sort(arr,left,r);
        }
        //向右递归
        if (right>l){
            sort(arr,l,right);
        }
    }

时间测试

快速排序8万数据,消耗时间1s不到
快速排序800万数据,消耗时间1s(希尔排序移动法需要3秒)——超级快,变态快

扫描二维码关注公众号,回复: 9941995 查看本文章

(5)简单选择排序

基本介绍

简单选择排序是每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,属于不稳定排序。
在这里插入图片描述

代码示例

    public static void selectSort(int[] arr){
        //选择排序是嵌套for循环,所以时间复杂度为O(n^2)
        for (int i = 0; i < arr.length-1; i++) {
            //第一轮排序
            //先假设第一个为最小值
            int minIndex=i;
            int min=arr[i];

            //循环比较一下,找最小值,循环结束后,min值就是数组中真正的最小值了
            for (int j = i+1; j < arr.length; j++) {
                //如果要求由大到小排序,只需要把条件改成"min<arr[j]"
                if (min>arr[j]){
                    //说明当前最小值并不是最小值,还有更小的,所以把更小的赋值给min
                    min=arr[j];
                    minIndex=j;
                }
            }

            //把最小值放在最左端,交换位置
            if (minIndex!=i){
                arr[minIndex]=arr[i];
                arr[i]=min;
            }
            // System.out.println("第"+(i+1)+"轮排序后的结果:"+Arrays.toString(arr));
        }
    }

时间测试

80000个数据的数组,排序耗时8s

(6)堆排序

基本介绍

堆排序(Heapsort)是利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
在这里插入图片描述

代码示例

public class HeapSort {
    public static void main(String[] args) {
        //要求把数组进行升序排序,根据这个要求,确定使用的是大顶堆
        int arr[]={4,6,8,5,9,90,89,56,-999};
        heapSort(arr);
        System.out.println("数组="+ Arrays.toString(arr));


        int arr01[]=new int[8000000];
        for (int i = 0; i < 8000000; i++) {
            arr01[i]= (int) (Math.random()*8000000);
        }

        Date date1=new Date();
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1Str=simpleDateFormat.format(date1);
        System.out.println("排序前的时间是="+date1Str);

        heapSort(arr01);

        Date date2=new Date();
        String date2Str=simpleDateFormat.format(date2);
        System.out.println("排序后的时间是="+date2Str);

        //8千万数据排序,耗时37秒
        // 排序前的时间是=2019-11-07 21:23:44
        // 排序后的时间是=2019-11-07 21:24:21

        //8百万数据排序,耗时3秒
        // 排序前的时间是=2019-11-07 21:26:01
        // 排序后的时间是=2019-11-07 21:26:04

    }

    //编写一个堆排序的方法,参数是一个数组,给它一个数组,就这个方法就能求出结果
    public static void heapSort(int arr[]){
        int temp=0;
        System.out.println("堆排序");
        //最重要的一部分就是把一个“无序二叉树”不断的调整成“大顶堆”

        //测试分布完成
        /*adjustHeap(arr,1,arr.length);
        System.out.println("第一次:"+ Arrays.toString(arr));//第一次:[4, 9, 8, 5, 6]

        adjustHeap(arr,0,arr.length);
        System.out.println("第二次:"+ Arrays.toString(arr));//第二次:[9, 6, 8, 5, 4]*/


        //把上面的分步完成完善,完成最终的代码
        //根据非叶子节点的计算公式,得到第一个非叶子节点,然后i递减,最后变成0,到根节点
        for (int i = arr.length/2-1; i >= 0; i--) {
            adjustHeap(arr,i,arr.length);
        }
        for (int j=arr.length-1; j>0;j--){
            //交换位置
            temp=arr[j];
            arr[j]=arr[0];
            arr[0]=temp;
            adjustHeap(arr,0,j);
        }
        // System.out.println("数组="+ Arrays.toString(arr));


    }

    //把一个给定的数组(二叉树),调整成我们想要的大顶堆
    //arr就是待调整的数组,i代表非叶子节点在数组中的索引,length就是还有多少个元素需要进行调整,length在逐渐减少
    //这个方法用来:把i指向的非叶子节点的树,调整成一个大顶堆
    public static void adjustHeap(int arr[], int i, int length){
        //首先,取出来当前元素的值,保存在临时变量
        int temp=arr[i];
        //开始调整
        for (int k = i*2+1; k <length ; k=k*2+1) {
            //k = i*2+1,k就是i的左子节点,k=k*2+1,就是借着找k的左子节点,并且这些节点都在数组的length内
            //1-如果左子节点<右子节点
            if(k+1<length && arr[k]<arr[k+1]){
                //就让k指向右子节点,因为调整时,i要和自己最大的子节点进行位置交换
                k++;
            }
            //2-如果i非叶子节点比它的子节点小,那就要调整位置了,利用临时变量来交换位置
            if(temp<arr[k]){
                arr[i]=arr[k];//把较大的值赋给当前节点
                i=k;//当前节点为i,现在变成k,也就是把非叶子节点的索引i往子节点身上移了
            } else {
                //如果父节点大于两个子节点,那就算了,不需要调整
                break;
            }
        }
        //当for循环结束以后,我们已经把i为父节点的树的最大值,放在了最顶上(局部,不是全部)
        arr[i]=temp;//把temp的值放到最后调整后的位置
    }

}

测试结果

8百万数据排序,耗时3秒
8千万数据排序,耗时37秒

(7)归并排序

基本介绍

归并排序是建立在归并操作上的一种有效的排序算法,采用分治法。首先考虑下如何将2个有序数列合并。这个非常简单,只要从比较2个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。

在这里插入图片描述

合并方法

    /**合并的方法
     * @MethodName: merge
     * @param arr 排序的原始数组
     * @param left 左边有序序列的初始索引
     * @param right 右边索引
     * @param mid 中间索引
     * @param temp 做中转功能的数组
     *
     * @Author: AllenSun
     * @Date: 2019/10/24 20:00
     */
    public static void merge(int arr[], int left, int mid, int right, int temp[]){
        System.out.println("运行了一次");//8个数合并了7次,10个数合并了9次
        int i=left;//初始化i,左边有序序列的初始索引
        int j=mid+1;//初始化j,右边有序序列的初始索引
        int t=0;//指向temp数组的当前索引(中转表也需要索引,不然怎么知道插入的位置)

        //(第一步)
        //先把左右两边(有序)的数据按照规则填充到temp数组
        //直到左右两边的有序序列,有一边处理完毕为止
        while (i<=mid && j<=right){
            //如果左边的有序序列的当前元素,小于等于右边有序序列的当前元素
            //即左边的当前元素,填充到temp数组
            //然后t++,i++
            if (arr[i]<=arr[j]){
                temp[t]=arr[i];
                t+=1;
                i+=1;
            }else {//反之,把右边有序序列的当前元素,填充到temp数组
                temp[t]=arr[j];
                t+=1;
                j+=1;
            }
        }
        //(第二步)
        //把有剩余数据的一边的数据一次全部填充到temp
        while (i<=mid){//左边的有序序列还有剩余的元素,全部填充到temp
            temp[t]=arr[i];
            t+=1;
            i+=1;
        }
        while (j<=right){
            temp[t]=arr[j];
            t+=1;
            j+=1;
        }
        //(第三步)
        //把temp数组的元素拷贝到arr
        //注意,并不是每次都拷贝所有
        t=0;
        int tempLeft=left;
        //打印出来每次索引的位置
        System.out.println("tempLeft="+tempLeft+" right="+right);
        while (tempLeft<=right){
            arr[tempLeft]=temp[t];
            t+=1;
            tempLeft+=1;
        }
    }

分解+合并的方法

    /**分解+合并的方法
     * @MethodName: mergeSort
     * @Author: AllenSun
     * @Date: 2019/10/24 20:41
     */
    public static void mergeSort(int arr[], int left, int right, int temp[]){
        if (left<right){
            int mid=(left+right)/2;//中间索引
            //向左递归进行分解
            mergeSort(arr, left, mid, temp);
            //向右递归进行分解
            mergeSort(arr, mid+1, right, temp);
            //到合并
            merge(arr, left, mid, right, temp);
        }
    }

时间测试

8万数据,耗时1秒
800万,耗时4秒

(8)基数排序

基本介绍

基数排序又叫“桶子法”,是桶排序的扩展,是将整数按位数切割成不同的数字,然后按每个位数分别比较。首先创建数组A[MaxValue];然后将每个数放到相应的位置上(如8放在下标8的数组位置);最后遍历数组,即为排序后的结果。

单个排序

    public static void sort01(int[] arr){
        //第一轮排序
        //定义一个二维数组,表示10个桶,每个桶就是一个一维数组
        //10是因为0-9有十位数,arr.length是因为一个桶最多能把所有数都放进去
        int[][] bucket=new int[10][arr.length];
        //定义一个一维数组来记录每个桶每次放入的数据个数
        int bucketElementCounts[]=new int[10];

        for (int j = 0; j < arr.length; j++) {
            int digitOfElement=0;
            //找到每个数个位为多少
            digitOfElement = arr[j] % 10;
            bucket[digitOfElement][bucketElementCounts[digitOfElement]]=arr[j];
            bucketElementCounts[digitOfElement]++;
        }

        //按照这个桶的顺序(一维数组的下标一次取出数据,放入原来数组)
        int index=0;
        //遍历每一个桶,并且把桶里的数据放入原来的数组
        for (int k=0; k<bucketElementCounts.length; k++){
            if (bucketElementCounts[k] !=0){//如果这个桶里数据数不为零,那就遍历这个桶
                //循环这个桶,就是第k个桶(就是第k个一维数组),放入
                for (int l = 0; l < bucketElementCounts[k]; l++) {
                    //取出元素放到arr
                    arr[index++]=bucket[k][l];
                }
            }
            //第一轮处理后,把每个bucketElementCounts[k]=0!!!
            bucketElementCounts[k]=0;
        }
    }

    public static void sort02(int[] arr){
        //第一轮排序
        //定义一个二维数组,表示10个桶,每个桶就是一个一维数组
        //10是因为0-9有十位数,arr.length是因为一个桶最多能把所有数都放进去
        int[][] bucket=new int[10][arr.length];
        //定义一个一维数组来记录每个桶每次放入的数据个数
        int bucketElementCounts[]=new int[10];

        for (int j = 0; j < arr.length; j++) {
            int digitOfElement=0;
            //找到每个数个位为多少
            digitOfElement = arr[j] /10 % 10;
            bucket[digitOfElement][bucketElementCounts[digitOfElement]]=arr[j];
            bucketElementCounts[digitOfElement]++;
        }

        //按照这个桶的顺序(一维数组的下标一次取出数据,放入原来数组)
        int index=0;
        //遍历每一个桶,并且把桶里的数据放入原来的数组
        for (int k=0; k<bucketElementCounts.length; k++){
            if (bucketElementCounts[k] !=0){//如果这个桶里数据数不为零,那就遍历这个桶
                //循环这个桶,就是第k个桶(就是第k个一维数组),放入
                for (int l = 0; l < bucketElementCounts[k]; l++) {
                    //取出元素放到arr
                    arr[index++]=bucket[k][l];
                }
            }
            bucketElementCounts[k]=0;
        }
    }


    public static void sort03(int[] arr){
        //第一轮排序
        //定义一个二维数组,表示10个桶,每个桶就是一个一维数组
        //10是因为0-9有十位数,arr.length是因为一个桶最多能把所有数都放进去
        int[][] bucket=new int[10][arr.length];
        //定义一个一维数组来记录每个桶每次放入的数据个数
        int bucketElementCounts[]=new int[10];

        for (int j = 0; j < arr.length; j++) {
            int digitOfElement=0;
            //找到每个数个位为多少
            digitOfElement = arr[j] /10 /10 % 10;
            bucket[digitOfElement][bucketElementCounts[digitOfElement]]=arr[j];
            bucketElementCounts[digitOfElement]++;
        }

        //按照这个桶的顺序(一维数组的下标一次取出数据,放入原来数组)
        int index=0;
        //遍历每一个桶,并且把桶里的数据放入原来的数组
        for (int k=0; k<bucketElementCounts.length; k++){
            if (bucketElementCounts[k] !=0){//如果这个桶里数据数不为零,那就遍历这个桶
                //循环这个桶,就是第k个桶(就是第k个一维数组),放入
                for (int l = 0; l < bucketElementCounts[k]; l++) {
                    //取出元素放到arr
                    arr[index++]=bucket[k][l];
                }
            }
            bucketElementCounts[k]=0;
        }
    }

整合排序

    public static void sort01(int[] arr){

        //1-得到数组中最大的数的位数
        int max=arr[0];//假设第一位数就是最大数
        for (int i = 0; i < arr.length; i++) {
            if (arr[i]>max){
                max=arr[i];
            }
        }
        //得到最大数是几位数
        int maxLength=(max+"").length();

        //第一轮排序
        //定义一个二维数组,表示10个桶,每个桶就是一个一维数组
        //10是因为0-9有十位数,arr.length是因为一个桶最多能把所有数都放进去
        int[][] bucket=new int[10][arr.length];
        //定义一个一维数组来记录每个桶每次放入的数据个数
        int bucketElementCounts[]=new int[10];

        //这里我们使用循环把代码处理一下
        for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
            //针对每个元素的对应位进行排序处理,第一次是个位,第二次是十位,第三次是百位

            for (int j = 0; j < arr.length; j++) {
                int digitOfElement=0;
                //取出每个元素的对应位的值
                digitOfElement = arr[j] / n % 10;
                //放入到对应的痛中
                bucket[digitOfElement][bucketElementCounts[digitOfElement]]=arr[j];
                bucketElementCounts[digitOfElement]++;
            }

            //按照这个桶的顺序(一维数组的下标一次取出数据,放入原来数组)
            int index=0;
            //遍历每一个桶,并且把桶里的数据放入原来的数组
            for (int k=0; k<bucketElementCounts.length; k++){
                if (bucketElementCounts[k] !=0){//如果这个桶里数据数不为零,那就遍历这个桶
                    //循环这个桶,就是第k个桶(就是第k个一维数组),放入
                    for (int l = 0; l < bucketElementCounts[k]; l++) {
                        //取出元素放到arr
                        arr[index++]=bucket[k][l];
                    }
                }
                //第一轮处理后,把每个bucketElementCounts[k]=0!!!
                bucketElementCounts[k]=0;
            }
            System.out.println("第"+(i+1)+"轮,排序结果为:"+Arrays.toString(arr));
        }
    }

时间测试

8万数据,耗时不到1秒
800万数据,耗时不到1秒
8000万数据,耗时还是不到1秒
8亿数据溢出了,典型的“用空间换时间”

发布了41 篇原创文章 · 获赞 5 · 访问量 658

猜你喜欢

转载自blog.csdn.net/weixin_44823875/article/details/104912246