🧡数据结构与算法🧡从零到有系列《七》基数、冒泡排序

260 阅读2分钟

这是我参与8月更文挑战的第19天,活动详情查看:8月更文挑战

上一篇说到了数据结构与算法中的排序算法今天这篇文章主要说说基础排序和冒泡排序

基数排序

介绍

基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m)

基数排序是1887年赫尔曼、何乐礼发明的。思想是讲整数按位数切割成不同的数字,然后按每个位数分别比较。

思想

讲所有的待比较数值统一设置为同样的数位长度,位数比较短的数前面补零,然后从最地位开始依次进行一次排序,这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

image.png

基数排序代码实现

讲数组53,542,3,63,14,214,154,748,616进行排序

/**

 * author:韩国庆

 * date:2021/3/8 16:37

 * version:1.0

 */

public class BasicSort {

 

    public static void main(String[] args) {

 

        int[] arrays = new int[]{53, 542, 3, 63, 14, 214, 154, 748, 616};

        Date before = new Date();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd
        HH:mm:ss:SS");

        System.out.println("排序前:" + simpleDateFormat.format(before));

 

 

        sort(arrays);

 

 

        Date after = new Date();

        System.out.println("排序后:" + simpleDateFormat.format(after));

 

    }

 

    public static void sort(int[] arrays) {

 

        /**

         * 得到数组中最大位数

         */

        //假设第一个位就是最大数

        int max = arrays[0];

        for (int i = 0; i < arrays.length; i++) {

            if (arrays[i] > max) {

                max = arrays[i];

            }

        }

 

        //得到最大位数的位数

        int maxLength = (max + "").length();

 

        /**

         * 定义一个二维数组,大小是10,表示10个桶,每一个桶则是一个数组
         * 二维数组包含10个一维数组

         * 为了防止在放入数据时数据溢出, 则把每个桶设置为arrays.length的大小。

         * 基数排序则是典型的空间换时间的算法

         */

        int[][] bucket = new int[10][arrays.length];

 

        /**

         * 为了记录每个桶中实际存放了多少个数据,我们定义一个一维数组来记录各个桶的每次放入的数据个数

         * 比如:bucketElementCount[0] 记录着bucket[0]桶中的元素个数

         */

        int[] bucketElementCount = new int[10];

 

 

        for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {

 

            /**

             * 循环取出每一位,比如先去个位,十位,百位...

             */

            for (int j = 0; j < arrays.length; j++) {

                /**

                 * 取出每一个元素对应的位数,

                 */

                int locationElement = arrays[j] / n % 10;

 

                /**

                 * 放入对用的桶中

                 */

                bucket[locationElement][bucketElementCount[locationElement]] = arrays[j];
                bucketElementCount[locationElement]++;

 

                /**

                 * 根据一维数组的下标依次取出数据,放入原数组中

                 */

                int index = 0;

                /**

                 * 遍历每一个桶,将数组放入原数组中

                 */

                for (int k = 0; k < bucketElementCount.length; k++) {

                    if (bucketElementCount[k] != 0) {

 

                        //循环第k个桶(第k个一维数组)

                        for (int l = 0; l < bucketElementCount[k]; l++) {

                            arrays[index++] = bucket[k][l];

                        }

                    }

 

                    //取出后需要将每一个bucketElementCount[k]置为0

                    bucketElementCount[k] = 0;

 

                }

 

            }

 

        }

 

        /**

         * 第一轮比较  个位数比较

         */
         for (int j=0;j<arrays.length;j++){

            int locationElement = arrays[j]/1%10;

            bucket[locationElement][bucketElementCount[locationElement]] = arrays[j];

            bucketElementCount[locationElement]++;

        }

 

        /**

         * 按照这个顺序依次取出放入原数组

         */

        int index = 0;

        for (int k=0;k<bucketElementCount.length;k++){

            if (bucketElementCount[k] !=0){

                for (int l = 0;l<bucketElementCount[k];l++){

                    arrays[index++] = bucket[k][l];

                }

            }

            //将bucketElementCount[k] 置为0

            bucketElementCount[k] = 0;

        }

 

        System.out.println("第一轮:对个位排序处理  "+ Arrays.toString(arrays));

 

        /**

         * 第二轮:针对十位进行排序

         */

        for (int j=0;j<arrays.length;j++){

            int locationElement = arrays[j]/10%10;

            bucket[locationElement][bucketElementCount[locationElement]] = arrays[j];
            bucketElementCount[locationElement]++;

        }

 

        index = 0;

        for (int k=0;k<bucketElementCount.length;k++){

            if (bucketElementCount[k] !=0){

                for (int l = 0;l<bucketElementCount[k];l++){

                    arrays[index++] = bucket[k][l];

                }

            }

            //将bucketElementCount[k] 置为0

            bucketElementCount[k] = 0;

        }

        System.out.println("第二轮:对十位排序处理  "+ Arrays.toString(arrays));

 

        /**

         * 第三轮:针对百位进行排序

         */

        for (int j=0;j<arrays.length;j++){

            int locationElement = arrays[j]/100%10;

            bucket[locationElement][bucketElementCount[locationElement]] = arrays[j];

            bucketElementCount[locationElement]++;

        }

 

        index = 0;

        for (int k=0;k<bucketElementCount.length;k++){

            if (bucketElementCount[k] !=0){

                for (int l = 0;l<bucketElementCount[k];l++){

                    arrays[index++] = bucket[k][l];
                    }

            }

            //将bucketElementCount[k] 置为0

            bucketElementCount[k] = 0;

        }

        System.out.println("第三轮:对百位排序处理  "+ Arrays.toString(arrays));

    }

}

🧡冒泡排序

介绍

冒泡排序的思想是通过对待排序序列从前往后依次比较相邻元素值,若发现逆序则交换,使值较大的元素从前逐步移向后面,就想水中气泡。

image.png

特点:

1、 需要循环array.length-1次 外层循环

2、 每次排序的次数逐步递减

3、 也可能存在本次排序没有发生变化

冒泡排序实际应用

/**

 * author:韩国庆

 * date:2021/3/9 16:04
 * version:1.0

 */

public class BubblingSort {

 

    public static void main(String[] args) {

 

        int[] arrays = new int[]{2,4,1,3,8,5,9,6,7};

 

 

        int temp = 0;

        boolean flag = false;

        for (int i=0;i<arrays.length-1;i++){

            for (int j=0;j<arrays.length-1-i;j++){

                if (arrays[j]>arrays[j+1]){

                    flag=true;

                    temp = arrays[j];

                    arrays[j] = arrays[j+1];

                    arrays[j+1] = temp;

 

                }

            }

            if (!flag){//在排序过程中,没有发生一次交换

                break;

            }else {

                flag = false;

            }

 

        }

 

        System.out.println(Arrays.toString(arrays));
        }

 

}