import java.util.Arrays;
/**
 * 选择排序
 * <p>
 * 第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,
 * 然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。
 * 以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法
 */
public class SelectionSort {
    public static void main(String[] args) {
        // 测试次数
        int times = 50000;
        int maxNum = 100;
        int maxSize = 100;
        for (int i = 0; i < times; i++) {
            // 生成随机数组
            int[] arr1 = generateArray(maxNum, maxSize);
            // 复制
            int[] arr2 = copyArray(arr1);
            // 选择排序
            selectionSort(arr1);
            // Api排序
            Arrays.sort(arr2);
            // 比较排序结果
            if (!arrayEquals(arr1, arr2)) {
                System.out.println("Sort failed!!!");
                System.out.println(Arrays.toString(arr1));
                System.out.println(Arrays.toString(arr2));
                return;
            }
        }
        System.out.println("Sort success");
    }
    /**
     * 选择排序
     *
     * @param arr 需要排序的数组
     */
    private static void selectionSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                minIndex = arr[j] < arr[minIndex] ? j : minIndex;
            }
            swap(arr, i, minIndex);
        }
    }
    /**
     * 生成随机数组
     *
     * @param maxNum  最大数
     * @param maxSize 数组最大大小
     * @return 随机数组
     */
    private static int[] generateArray(int maxNum, int maxSize) {
        int[] arr = new int[(int) (maxSize * Math.random())];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (maxNum * Math.random()) - (int) (maxNum * Math.random());
        }
        return arr;
    }
    /**
     * 判断两数组是否完全相同
     *
     * @param arr1 数组1
     * @param arr2 数组2
     * @return 是否相同
     */
    private static boolean arrayEquals(int[] arr1, int[] arr2) {
        if (arr1 == arr2) {
            return true;
        }
        if (arr1 == null || arr2 == null || arr1.length != arr2.length) {
            return false;
        }
        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] != arr2[i]) {
                return false;
            }
        }
        return true;
    }
    /**
     * 复制数组
     *
     * @param arr 要复制的数组
     * @return 复制的数组
     */
    private static int[] copyArray(int[] arr) {
        if (arr == null) {
            throw new NullPointerException();
        }
        int[] copy = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            copy[i] = arr[i];
        }
        return copy;
    }
    /**
     * 交换数组两个元素的位置
     *
     * @param arr 数组
     * @param i   位置
     * @param j   位置
     */
    private static void swap(int[] arr, int i, int j) {
        // 同一个位置交换无意义,并且用异或交换会有问题
        if (i == j) {
            return;
        }
        // 交换
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }
}