import java.util.Arrays;
import java.util.Random;

public class SortMe {
    public static void main(String[] args) {
        //int [] arr = {1,3,2,9,5,4,6,7};
        int arrLength = 10000;
        int[] arr = new int[arrLength];

        for (int i = 0; i < arrLength; i++) {
            arr[i] = new Random().nextInt(arrLength);
            //arr[i] = i;  // 如果是基本有序,插入排序最快
        }

        int[]  narr = generateRandomArray(arrLength,arrLength);

        int[] arrNew1 = Arrays.copyOf(narr,narr.length);
        int[] arrNew2 = Arrays.copyOf(narr,narr.length);

        //SortMe.printArr(arr);
        long s1 = System.currentTimeMillis();
        SortMe.selectionSort(arrNew1);
        long s2 = System.currentTimeMillis();
        System.out.println("选择排序:"+(s2 - s1));

        s1 = System.currentTimeMillis();
        SortMe.insertSort(narr);
        s2 = System.currentTimeMillis();
        System.out.println("插入排序:"+(s2 - s1));

        //SortMe.bubbleSort(arr);

        s1 = System.currentTimeMillis();
        SortMe.quickSort(arrNew2);
        s2 = System.currentTimeMillis();
        System.out.println("快速排序:"+(s2 - s1));

        System.out.println(isEqual(arrNew1,narr,arrLength));
        System.out.println(isEqual(arrNew2,narr,arrLength));

        //int alength = 20;
        //int[]  narr = generateRandomArray(alength,100);
        //printArr(narr);
    }


    public static int[] generateRandomArray(int maxSize, int maxValue){
        // Math.random()  [0,1)
        // 产生一个长度随机的数组
        int[] arr = new int[(int)((maxSize+1)*Math.random())];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int)((maxValue+1)*Math.random()) - (int)(maxValue*Math.random());
        }

        return arr;
    }

    // 比较两个数组是否相等
    private static boolean isEqual(int[]arr1,int[] arr2,int arrLength){
        for (int i = 0; i < arr1.length; i++) {
            if(arr1[i] != arr2[i]){
                return false;
            }
        }

        return true;
    }

    public static void printArr(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.printf(arr[i]+" ");
        }
        System.out.println();
    }

    // 选择排序
    public static void selectionSort(int[] arr){
        if(null == arr || arr.length < 2){
            return;
        }

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

    private static void swap(int[] arr, int i, int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
//        arr[i] = arr[i] ^ arr[j];
//        arr[j] = arr[i] ^ arr[j];
//        arr[i] = arr[i] ^ arr[j];
    }

    // 冒泡排序
    public static void bubbleSort(int[] arr){
        if(null == arr || arr.length < 2){
            return;
        }

        for (int e = arr.length-1; e>0; e--) { // 0 ~ e
            for (int i = 0; i < e; i++) {
                if(arr[i] > arr[i+1]){
                    swap(arr,i,i+1);
                }
            }
        }
    }

    // 插入排序
    public static void insertSort(int[] arr){
        if(null == arr || arr.length < 2){
            return;
        }

        for (int i = 1; i < arr.length; i++) {
            for (int j = i-1; j >=0 && arr[j] >arr[j+1]; j--) {
                swap(arr,j,j+1);
            }
        }
    }

    // 快速排序
    public static void quickSort(int[] arr){
        quickSort(arr, 0, arr.length-1);
    }

    public static void quickSort(int[] arr, int left, int right){
        if(left>=right){
            return;
        }

        int partition = partition(arr,left,right);
        quickSort(arr,left,partition-1);
        quickSort(arr,partition+1,right);
    }

    private static int partition(int[] arr, int left, int right){
        int l = left+1;
        int r = right;
        //for (int i = left+1; i < arr.length-1; i++) {
        //l = i+1;
        //r = arr.length-1;
        while(l <= r) {
            while ( l<=r && arr[left] > arr[l]) {
                l++;
            }

            while (l<=r && arr[left] <= arr[r] ) {
                r--;
            }

            if(r < l){
                break;
            }
            swap(arr,l, r);
        }

        swap(arr,left,r);
        // }
        return r;
    }
}