排序算法-简单排序01


前言

对数组中的整数排序是常见的算法, 其中简单排序是最基础的算法


一、思路

各排序算法见代码注释;无外乎 选定一个位置或指定数,按规则比较后交换

二、题解

选择排序

public class Code01_SelectionSort {

    /**
     * 选择排序  1-n-1  将比较后的最小值放在 0 位
     *          2-n-1  将比较后的最小值放在 1 位
     *          拿到每次完成循环中的最小值 和 arr[i] 交换;  查询最小值过程可以不交换, 知道最小值的索引即可
     *
     * @param arr
     */
    private static void selectionSort(int[] arr) {
        // 排除特殊情况
        if (arr == null || arr.length < 2) {
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            int minIndex = i;
            for(int j= i+1;j<arr.length;j++) {
                minIndex = arr[j] < arr[minIndex] ? j : minIndex;
            }
            // 将最小值交换到 minIndex位置上
            swap(arr, i,minIndex);
        }

    }

    /**
     * 常规的 2 数交换
     * @param arr
     * @param i
     * @param j
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }


    /**
     * 创建一个随机数的数组
     *
     * @param maxSize  数组最大容量
     * @param maxValue 数组元素 最大值
     * @return
     */
    private static int[] generateRandomArray(int maxSize, int maxValue) {
        // Math.random() [0 1)
        // Math.random() * N [0, N)
        int[] arr = new int[(int) (Math.random() * (maxSize + 1))];
        // 每个元素赋值
        for (int i = 0; i < arr.length; i++) {

            //这种写法可以产生复数
            arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
            //只能由正整数
            //arr[i] = (int) ((maxValue + 1) * Math.random());
        }
        return arr;

    }

    /**
     *  复制一个数组
     * @param arr
     */
    private static int[] copyArray(int[] arr) {
        if(arr == null) {
            return null;
        }
        int[] res = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            res[i] = arr[i];
        }
        return res;
    }

    //打印数组中的元素
    private static void printArray(int[] arr) {
        if (arr == null) {
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    /**
     *  比较器, 用 java 数组api排序 
     * @param arr
     */
    private static void comparator(int[] arr) {
        Arrays.sort(arr);
    }

    /**
     *  比较2 数组是否相等
     * @param arr1
     * @param arr2
     * @return
     */
    private static boolean isEqual(int[] arr1, int[] arr2) {
        if ((arr1 != null && arr2 == null) || (arr1 == null && arr2 != null)) {
            return false;
        } 
        if(arr1 == null && arr2 == null) {
            return true;   
        } 
        if(arr1.length != arr2.length) {
            return false;
        } 
        // 比较每个元素 
        for (int i = 0; i < arr1.length; i++) {
            if(arr1[i] != arr2[i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * 主程序
     * @param args
     */
    public static void main(String[] args) {
        int maxSize = 100;
        int maxValue = 100;
        int maxTimes = 500000;
        boolean success = true;
        for (int i = 0; i < maxTimes; i++) {
            int[] arr1 = generateRandomArray(maxSize, maxValue);
            int[] arr2 = copyArray(arr1);
            selectionSort(arr1);
            comparator(arr2);
            if(!isEqual(arr1, arr2)) {
                success =false;
                printArray(arr1);
                printArray(arr2);
                break;
            }
        }
        System.out.println(success ? "Nice!":"Bad");

        int[] arr = generateRandomArray(maxSize, maxValue);
        printArray(arr);
        selectionSort(arr);
        printArray(arr);
    }
}

冒泡排序

public class Code02_BubbleSort {
    /**
     * 冒泡排序
     * 思路: 两两比较, 大的数交换到右侧
     *   0 ~ n-1  比较 n-1 次  最大值在 arr[n-1] 上
     *   0 ~ n-2  比较 n-2 次  最大值在 arr[n-2] 上
     * @param arr
     */
    private static void bubbleSort(int[] arr) {
        // 排除特殊情况
        if (arr == null || arr.length < 2) {
            return;
        }
        for (int e = arr.length-1; e > 0; e--) {
            for(int i = 0; i< e;i++) {
                if(arr[i] > arr[i+1]) {
                    swap(arr, i, i+1);
                }
            }
        }
    }


    /**
     * 异或运算的 2 数交换
     * 满足交换律和结合律
     *  0 ^ N = N
     *  N ^ N = 0
     *  是不进位的二进制加法运算
     *   1001
     *   1111
     *   ----
     *   0110
     * @param arr
     * @param i
     * @param j
     */
    private 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];
    }


    /**
     * 创建一个随机数的数组
     *
     * @param maxSize  数组最大容量
     * @param maxValue 数组元素 最大值
     * @return
     */
    private static int[] generateRandomArray(int maxSize, int maxValue) {
        // Math.random() [0 1)
        // Math.random() * N [0, N)
        int[] arr = new int[(int) (Math.random() * (maxSize + 1))];
        // 每个元素赋值
        for (int i = 0; i < arr.length; i++) {

            //这种写法可以产生复数
            arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
            //只能由正整数
            //arr[i] = (int) ((maxValue + 1) * Math.random());
        }
        return arr;

    }

    /**
     *  复制一个数组
     * @param arr
     */
    private static int[] copyArray(int[] arr) {
        if(arr == null) {
            return null;
        }
        int[] res = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            res[i] = arr[i];
        }
        return res;
    }

    //打印数组中的元素
    private static void printArray(int[] arr) {
        if (arr == null) {
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    /**
     *  比较器, 用 java 数组api排序
     * @param arr
     */
    private static void comparator(int[] arr) {
        Arrays.sort(arr);
    }

    /**
     *  比较2 数组是否相等
     * @param arr1
     * @param arr2
     * @return
     */
    private static boolean isEqual(int[] arr1, int[] arr2) {
        if ((arr1 != null && arr2 == null) || (arr1 == null && arr2 != null)) {
            return false;
        }
        if(arr1 == null && arr2 == null) {
            return true;
        }
        if(arr1.length != arr2.length) {
            return false;
        }
        // 比较每个元素
        for (int i = 0; i < arr1.length; i++) {
            if(arr1[i] != arr2[i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * 主程序
     * @param args
     */
    public static void main(String[] args) {
        int maxSize = 100;
        int maxValue = 100;
        int maxTimes = 500000;
        boolean success = true;
        for (int i = 0; i < maxTimes; i++) {
            int[] arr1 = generateRandomArray(maxSize, maxValue);
            int[] arr2 = copyArray(arr1);
            bubbleSort(arr1);
            comparator(arr2);
            if(!isEqual(arr1, arr2)) {
                success =false;
                printArray(arr1);
                printArray(arr2);
                break;
            }
        }
        System.out.println(success ? "Nice!":"Bad");

        int[] arr = generateRandomArray(maxSize, maxValue);
        printArray(arr);
        bubbleSort(arr);
        printArray(arr);
    }
}

直接插入排序

public class Code03_InsertionSort {
    /**
     * 插入排序-直接插入
     * 思路: 选定一个数, 从它左侧开始比较;有遇到比它大的数进行交换;
     * 知道它左边是小的数, 右边是大的数, 有点类似于扑克牌插入合适的位置
     * @param arr
     */
    private static void insertionSort(int[] arr) {
        // 排除特殊情况
        if (arr == null || arr.length < 2) {
            return;
        }
        for (int i = 1; i < arr.length; i++) {
            // j 往左走; 如果左边碰到大的数需要交换; 碰到小的数直接跳出循环
            for(int j = i-1; j>=0 && arr[j]> arr[j+1]; j--) {
                swap(arr, j, j+1);
            }

        }

    }



    /**
     * 异或运算的 2 数交换
     * 满足交换律和结合律
     *  0 ^ N = N
     *  N ^ N = 0
     *  是不进位的二进制加法运算
     *   1001
     *   1111
     *   ----
     *   0110
     * @param arr
     * @param i
     * @param j
     */
    private 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];
    }


    /**
     * 创建一个随机数的数组
     *
     * @param maxSize  数组最大容量
     * @param maxValue 数组元素 最大值
     * @return
     */
    private static int[] generateRandomArray(int maxSize, int maxValue) {
        // Math.random() [0 1)
        // Math.random() * N [0, N)
        int[] arr = new int[(int) (Math.random() * (maxSize + 1))];
        // 每个元素赋值
        for (int i = 0; i < arr.length; i++) {

            //这种写法可以产生复数
            arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
            //只能由正整数
            //arr[i] = (int) ((maxValue + 1) * Math.random());
        }
        return arr;

    }

    /**
     *  复制一个数组
     * @param arr
     */
    private static int[] copyArray(int[] arr) {
        if(arr == null) {
            return null;
        }
        int[] res = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            res[i] = arr[i];
        }
        return res;
    }

    //打印数组中的元素
    private static void printArray(int[] arr) {
        if (arr == null) {
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    /**
     *  比较器, 用 java 数组api排序
     * @param arr
     */
    private static void comparator(int[] arr) {
        Arrays.sort(arr);
    }

    /**
     *  比较2 数组是否相等
     * @param arr1
     * @param arr2
     * @return
     */
    private static boolean isEqual(int[] arr1, int[] arr2) {
        if ((arr1 != null && arr2 == null) || (arr1 == null && arr2 != null)) {
            return false;
        }
        if(arr1 == null && arr2 == null) {
            return true;
        }
        if(arr1.length != arr2.length) {
            return false;
        }
        // 比较每个元素
        for (int i = 0; i < arr1.length; i++) {
            if(arr1[i] != arr2[i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * 主程序
     * @param args
     */
    public static void main(String[] args) {
        int maxSize = 100;
        int maxValue = 100;
        int maxTimes = 500000;
        boolean success = true;
        for (int i = 0; i < maxTimes; i++) {
            int[] arr1 = generateRandomArray(maxSize, maxValue);
            int[] arr2 = copyArray(arr1);
            insertionSort(arr1);
            comparator(arr2);
            if(!isEqual(arr1, arr2)) {
                success =false;
                printArray(arr1);
                printArray(arr2);
                break;
            }
        }
        System.out.println(success ? "Nice!":"Bad");

        int[] arr = generateRandomArray(maxSize, maxValue);
        printArray(arr);
        insertionSort(arr);
        printArray(arr);
    }
}

总结

简单排序, 数组元素左右比较, 按规则交换

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值