排序算法(一)四种冒泡排序

SortUtil.java

package com.zby.sort;

import java.util.Arrays;
import java.util.Random;
import java.util.function.Consumer;

/**
 * @author zby
 * @title SortUtil
 * @date 2019年7月15日
 * @description 排序工具类
 */
public class SortUtil {

    // 打印排序数组的阀值
    public static int PRINT_THRESHOLD = 100;

    /**
     * 
     * @param size
     * @return 获取一个随机数组
     */
    public static int[] getIntArray(int size) {
        System.out.println("数组大小:" + size);
        // 初始化待排序数组
        int[] arrOrig = new int[size];
        for (int i = 0; i < size; i++) {
            Random random = new Random();
            arrOrig[i] = random.nextInt(size + 100);
        }
        if (arrOrig.length <= PRINT_THRESHOLD) {
            System.out.println("排序前数组:" + Arrays.toString(arrOrig));
        }
        return arrOrig;
    }

    /**
     * 封装排序算法运行
     * 
     * @param name     算法名称
     * @param arrOrig  待排序数组
     * @param consumer 排序算法
     */
    public static void run(String name, int[] arrOrig, Consumer<int[]> consumer) {
        System.out.println("********************");
        int[] arr = new int[arrOrig.length];
        System.arraycopy(arrOrig, 0, arr, 0, arrOrig.length);
        Long start = System.currentTimeMillis();
        consumer.accept(arr);
        System.out.printf("%s 耗时 :%d ms \n", name, System.currentTimeMillis() - start);
        if (arrOrig.length <= PRINT_THRESHOLD) {
            System.out.println("排序后:" + Arrays.toString(arr));
        }
    }
}

BubbleSort.java

package com.zby.sort;

/**
 * @author zby
 * @title BubbleSort
 * @date 2019年7月9日
 * @description 冒泡排序
 */
public class BubbleSort {

    public static void main(String[] args) {
        run(10);
        run(10000);
        run(100000);
    }

    /**
     * 使用工具类排序
     * 
     * @param size
     */
    private static void run(int size) {
        int[] intArrayShiwan = SortUtil.getIntArray(size);
        SortUtil.run("冒泡排序(临时变量交换)", intArrayShiwan, BubbleSort::bubbleSortWithTempExchange);
        SortUtil.run("冒泡排序(异或交换)", intArrayShiwan, BubbleSort::bubbleSortWithXorExchange);
        SortUtil.run("冒泡排序(趟数优化)", intArrayShiwan, BubbleSort::bubbleSortRanksOptimize);
        SortUtil.run("冒泡排序(交换优化)", intArrayShiwan, BubbleSort::bubbleSortExchangeOptimize);
    }

    /**
     * 冒泡排序(临时变量交换)
     * 
     * @param arr 待排序数组
     */
    public static void bubbleSortWithTempExchange(int[] arr) {
        int temp;
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    /**
     * 冒泡排序(异或交换)
     * 
     * @param arr 待排序数组
     */
    public static void bubbleSortWithXorExchange(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    arr[j] = arr[j] ^ arr[j + 1];
                    arr[j + 1] = arr[j] ^ arr[j + 1];
                    arr[j] = arr[j] ^ arr[j + 1];
                }
            }
        }
    }

    /**
     * 冒泡排序比较趟数优化,但是多了判断、赋值
     * 
     * @param arr 待排序数组
     */
    @Deprecated
    public static void bubbleSortRanksOptimize(int[] arr) {
        int temp;
        for (int i = 0; i < arr.length - 1; i++) {
            boolean ordered = true;
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    ordered = false;
                }
            }
            if (ordered) {
                break;
            } else {
                ordered = true;
            }
        }
    }

    /**
     * 冒泡排序交换优化(使用冒泡的方式找最大值,使用索引的方式一趟一次交换)
     * 
     * @param arr 待排序数组
     */
    public static void bubbleSortExchangeOptimize(int[] arr) {
        int temp;
        int maxIndex;
        for (int i = 0; i < arr.length - 1; i++) {
            int lastIndex = arr.length - i - 1;
            maxIndex = 0;
            for (int j = 0; j <= lastIndex; j++) {
                if (arr[maxIndex] < arr[j]) {
                    maxIndex = j;
                }

            }
            if (lastIndex != maxIndex) {
                temp = arr[maxIndex];
                arr[maxIndex] = arr[lastIndex];
                arr[lastIndex] = temp;
            }
        }
    }

}

Console

数组大小:10
排序前数组:[36, 55, 5, 63, 42, 41, 46, 102, 63, 73]
********************
冒泡排序(临时变量交换) 耗时 :0 ms 
排序后:[5, 36, 41, 42, 46, 55, 63, 63, 73, 102]
********************
冒泡排序(异或交换) 耗时 :0 ms 
排序后:[5, 36, 41, 42, 46, 55, 63, 63, 73, 102]
********************
冒泡排序(趟数优化) 耗时 :0 ms 
排序后:[5, 36, 41, 42, 46, 55, 63, 63, 73, 102]
********************
冒泡排序(交换优化) 耗时 :0 ms 
排序后:[5, 36, 41, 42, 46, 55, 63, 63, 73, 102]
数组大小:10000
********************
冒泡排序(临时变量交换) 耗时 :220 ms 
********************
冒泡排序(异或交换) 耗时 :164 ms 
********************
冒泡排序(趟数优化) 耗时 :366 ms 
********************
冒泡排序(交换优化) 耗时 :87 ms 
数组大小:100000
********************
冒泡排序(临时变量交换) 耗时 :14894 ms 
********************
冒泡排序(异或交换) 耗时 :16083 ms 
********************
冒泡排序(趟数优化) 耗时 :14558 ms 
********************
冒泡排序(交换优化) 耗时 :4615 ms 

 结论

1、临时变量交换比异或交换快
2、趟数优化十分不稳定,只有在数组有序性比较高时优化效果才比较好,不推荐使用
3、直接记录最大索引,直到一趟最后交换比冒泡每次交换效率高很多

 

posted @ 2019-07-01 22:04  java拌饭  阅读(333)  评论(0编辑  收藏  举报