排序算法(更新中)

1. 在此先贡献一个网站 此网站可可视化各种排序算法的动画

排序算法动画

2. 冒泡排序

  • 对数器
/**
 * 对数器
 */
public class CheckMachine {

    /**
     * 交换两个位置
     *
     * @param arr
     * @param i
     * @param j
     */
    public static void swap(int arr[], int i, int j) {
        // 异或不可以交换同一个位置上
        if (i == j) return;
        // 异或实现交换
        /**
         * 1.异或就是无进位相加
         * 2.异或满足交换律
         * 3.N^N=0 0^N=N
         *  注意不可以交换同一个位置上的数 如果是同一个位置那么就是0
         */
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];

    }

    /**
     * 生成随机数组
     * @param maxLength
     * @return
     */
    public static int[] arrGen(int maxLength) {
        if (maxLength < 1) return null;
        //1. 随机长度的数组
        // maxLength+1 为了防止maxLength=1 的时候 数组为空
        int[] arr1 = new int[(int) (Math.random() * (maxLength+1))];
        for (int i = 0; i < arr1.length; i++) {
            // 为了让出现负数
            arr1[i] = (int) (Math.random() * maxLength - Math.random() * maxLength);
        }
        return arr1;
    }

    /**
     * 打印数组
     * @param arr1
     */
    public static void arrPrint(int[] arr1) {
        if (arr1 == null || arr1.length == 0) return;
        for (int i = 0; i < arr1.length; i++) {
            System.out.print(arr1[i] + " ");

        }
    }

    /**
     * 判断两个数组是否相等
     * @param arr1
     * @param arr2
     * @return
     */
    public static boolean arrEquals(int[] arr1, int[] arr2) {
        //1 长度相等
        if (arr1.length != arr1.length) return false;
        // 2 值相等
        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] != arr2[i]) return false;
        }
        return true;
    }

    /**
     * 复制数组
     * @param arr1
     * @return
     */
    public static int[] arrCopy(int[] arr1) {
        if (arr1 != null && arr1.length >= 0) {
            int[] arr = new int[arr1.length];
            for (int i = 0; i < arr1.length; i++) {
                arr[i] = arr1[i];

            }
            return arr;
        }
        throw new IllegalArgumentException("数组不可以为空");
    }

}


public class 冒泡排序 {
    @Test
    public void test() {
      long maxTime = 10990000L;
        int maxLength = 22;
        // 1.生成最大长度为maxLength的数组
        boolean falg = true;
        // 2.排序 maxTime次
        for (int i = 0; i < maxTime; i++) {
            int[] arr1 = CheckMachine.arrGen(maxLength);
            int[] arr2 = CheckMachine.arrCopy(arr1);
            bubblingSort(arr1);
            Arrays.sort(arr2);
            // 3 看排的对不对 和自带的数组排序比较 有一次不对 直接跳出循环
            if (!CheckMachine.arrEquals(arr1, arr2)) {
                falg = false;
                CheckMachine.arrPrint(arr1);
                break;
            }
        }

        System.out.println(falg ? "nice" : "fuck fucking");

    }

    /**
     * 冒泡排序:数组数值从前往后,两两依次比较, 前者大于后者交换,否则向前移动一位置,
     * 每次可将待排序的中最大值挑出来放到末尾。
     * 时间复杂度为O(n^2)
     *
     * @param arr
     */
    private static void bubblingSort(int[] arr) {

        if (arr.length <2 || arr == null) return;
        for (int i = 1; i < arr.length; i++) {
            for (int j = 0; j < arr.length-i ; j++) {
                if ( arr[j] > arr[j + 1] )
                    CheckMachine.swap(arr, j, j + 1);
            }
        }
    }
}

3. 插入排序


public class 插入排序 {
    @Test
    public void test() {
        long maxTime = 100L;
        int maxLength = 100;
        // 1.生成最大长度为maxLength的数组
        boolean falg = true;
        // 2.排序 maxTime次
        for (int i = 0; i < maxTime; i++) {
            int[] arr1 = CheckMachine.arrGen(maxLength);
            int[] arr2 = CheckMachine.arrCopy(arr1);
            insertSort(arr1);
            Arrays.sort(arr2);
            // 3 看排的对不对 和自带的数组排序比较 有一次不对 直接跳出循环
            if (!CheckMachine.arrEquals(arr1, arr2)) {
                falg = false;
                CheckMachine.arrPrint(arr1);
                break;
            }
        }
        System.out.println(falg ? "nice" : "fuck fucking");
    }
    /**
     * 插入排序: 将待排序的数挨个和他前面的数比较 一直到合适的位置为止。
     * 待排序的数比他前面的数小就交换,交换后还小再交换 一直到不小或者前面没数了为止
     * 0-1 范围有序 :
     * 0-2 范围有序:
     * 0-3 范围有序:
     * 复杂度 O(n^2)
     * @param arr
     */
    private void insertSort(int[] arr) {
        if (arr.length < 2 || arr == null) return;
        // 1 第一for循环 找出待比较的数
        for (int i = 1; i < arr.length; i++) {
            // 2 第二个for 依次比较两个数并且向前移动
            for (int j = i; j > 0; j--) {
                if (arr[j] < arr[j - 1]) {
                    CheckMachine.swap(arr, j, j - 1);
                } else break;
            }
        }
    }
}

4.选择排序


public class 选择排序 {
    /**
     * 对数器测试:
     * 什么是对数器:生成不同的测试数据 用来检测方法的正确性。
     * 在排序中对数器怎么生成:
     */
    @Test
    public void test1() {
        int maxTime = 10000;
        int maxLength = 10;
        // 1.生成最大长度为maxLength的数组
        boolean falg = true;
        // 2.排序 maxTime次
        for (int i = 0; i < maxTime; i++) {
            int[] arr1 = CheckMachine.arrGen(maxLength);
            int[] arr2 = CheckMachine.arrCopy(arr1);
            selectSort(arr1);
            Arrays.sort(arr2);
            // 3 看排的对不对 和自带的数组排序比较 有一次不对 直接跳出循环
            if (!CheckMachine.arrEquals(arr1, arr2)) {
                falg = false;
                CheckMachine.arrPrint(arr1);
                break;
            }
        }
        System.out.println(falg ? "nice" : "fuck fucking");

    }

    /**
     * 选择排序: 每次从未排序的元素中选最小值的放在已排元素的后面。
     *
     * @param arrs
     */
    private static void selectSort(int[] arrs) {
        // 1.数组长度为空或者是1 不排序直接返回
        if (arrs.length < 2 || arrs == null) {
            return;
        }
        //2.数组不为空 
        for (int i = 0; i < arrs.length; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arrs.length; j++) {
                // 找出最小值的位置
                minIndex = arrs[j] < arrs[minIndex] ? j : minIndex;
            }
            CheckMachine.swap(arrs, minIndex, i);

        }

    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值