• 选择、冒泡、插入排序,二分法和对数器


    package arithmetic;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    
    /**
     * @author hailu
     */
    public class Sort {
        /**
         * 选择排序
         */
        public static void selectionSort(int[] arr) {
            if (arr == null || arr.length < 2) {
                return;
            }
            /*
             * 0 ~ n-1
             * 1 ~ n-1
             * 2 ~ n-1
             * ...~ n-1
             * */
            // i ~ N-1
            for (int i = 0; i < arr.length - 1; i++) {
                // 最小值在哪个位置上  i~n-1
                int minIndex = i;
                // i ~ N-1 上找最小值的下标
                //从第二个开始,每个元素和左侧元素比较
                for (int j = i + 1; j < arr.length; j++) {
                    minIndex = arr[j] < arr[minIndex] ? j : minIndex;
                }
                swap(arr, i, minIndex);
            }
        }
    
        /**
         * 冒泡排序
         */
        public static void bubbleSort(int[] arr) {
            if (arr == null || arr.length < 2) {
                return;
            }
            // 0 ~ N-1
            // 0 ~ N-2
            // 0 ~ N-3
            //从最后一个元素开始
            for (int i = arr.length - 1; i > 0; i--) {
                for (int j = 0; j < i; j++) {
                    //从第一个元素开始,右侧相邻元素比较
                    if (arr[j] < arr[i + 1]) {
                        swap(arr, i, j + 1);
                    }
                }
            }
        }
    
        /**
         * 插入排序
         */
        public static void insertionSort(int[] arr) {
            if (arr == null || arr.length < 2) {
                return;
            }
            // 0~0 是有序的
            // 0~i 想有序
            for (int i = 1; i < arr.length; i++) {
                for (int j = i; j > 0; j--) {
                    if (arr[j] < arr[j - 1]) {
                        swap(arr, j, j - 1);
                    }
                }
            }
        }
    
        /**
         * 二分法:查找有序数组是否包含某个数字
         *
         * @param sortedArr
         * @param num
         * @return
         */
        public static boolean exist(int[] sortedArr, int num) {
            if (sortedArr == null || sortedArr.length == 0) {
                return false;
            }
            int L = 0;
            int R = sortedArr.length - 1;
    
            while (L < R) {
                // mid = (L+R) / 2;
                // L 10亿  R 18亿  超出int最大值
                // mid = L + (R - L) / 2
                // N / 2    N >> 1
                int mid = L + ((R - L) >> 1);
                if (sortedArr[mid] == num) {
                    return true;
                } else if (sortedArr[mid] > num) {
                    R = mid - 1;
                } else {
                    L = mid + 1;
                }
            }
            return sortedArr[L] == num;
        }
    
        /**
         * 二分法:在arr上,找满足>=value的最左位置
         *
         * @param arr
         * @param value
         * @return
         */
        public static int nearestIndex(int[] arr, int value) {
            int L = 0;
            int R = arr.length - 1;
            int index = -1;
            while (L <= R) {
                int mid = L + ((R - L) >> 1);
                //这里的 >= 符号和题干对应
                if (arr[mid] >= value) {
                    //更新index
                    index = mid;
                    R = mid - 1;
                } else {
                    L = mid + 1;
                }
            }
            return index;
        }
    
        /**
         * arr中,只有一种数,出现奇数次
         *
         * @param arr
         */
        public static void printOddTimesNum1(int[] arr) {
            //0^N -> N
            int eor = 0;
            for (int i = 0; i < arr.length; i++) {
                //异或异或满足交换律结合律,偶数次按位异或后为0
    //            eor=eor^arr[1];
    //            eor=eor^arr[2];
    //            eor=eor^arr[3];
                eor ^= arr[i];
            }
            System.out.println(eor);
        }
    
        //怎么把int数提取出最右侧的 1 ?
        //      N&((~N)+1)
        //N =        0000 1101 1000
        //~N=        1111 0010 0111
        //~N+1=      1111 0010 1000
        //N&((~N)+1)=0000 0000 1000 最右侧的 1 出现了
    
        /**
         * arr中有两种数出现了奇数次,其他数出现了偶数次,找到这两种数
         *
         * @param arr
         */
        public static void printOddTimesNum2(int[] arr) {
            //找到出现奇数次的两个数
            int eor = 0;
            for (int i = 0; i < arr.length; i++) {
                //偶数次最后位0
                // a!=b  -> eor!=0
                // a ,b 存在第 n 位不相同,eor必然有一个位置上是1
                // eor最后的结果是 a^b
                //第 n 位存在两种数  0(有奇有偶) 或 1(有奇有偶),但是 a 和 b 一定是分开的
                eor ^= arr[i];
            }
            // 提取出最右的 1  0000 0000 1000
            int rightOne = eor & ((~eor) + 1);
            //eor'
            int one = 0;
            for (int i = 0; i < arr.length; i++) {
                if ((arr[i] & rightOne) != 0) {
                    // 或者 if ((arr[i] & rightOne) == rightOne) {
    
                    // rightOne         0000 0001 0000
                    //arr[i]&rightOne   0000 1011 0000
                    //(arr[i]&rightOne)!=0 代表该位有 1
                    //
                    one ^= arr[i];
                }
            }
            int tow = eor ^ one;
            System.out.println(one + " " + tow);
        }
    
        /**
         * 任意数中二进制 1 的个数
         *
         * @param N
         * @return
         */
        public static int bit1counts(int num) {
            //方法1:循环32次
            //方法2:比循环32次要快
            int count = 0;
            while (num != 0) {
                int rightOne = num & ((~num) + 1);
                count++;
                //抹掉最后一个 1
                num ^= rightOne;
                //num为正数时可这么写: num -= rightOne
            }
            return count;
        }
    
        public static void main(String[] args) {
    //        int[] arr = new int[]{5, 3, 4, 1, 2};
    //        int[] arr = new int[]{1, 2, 3, 4, 5};
    //       System.out.println(nearestIndex(arr,4));
    //
    //        selectionSort(arr);
    //        boolean b=exist(arr,1);
    //        printArray(arr);
    //
    //        int testTime = 500000;
    //        int maxSize = 100;
    //        int maxValue = 100;
    //        boolean succeed = true;
    //        for (int i = 0; i < testTime; i++) {
    ////            int[] arr1 = generateRandomArray(maxSize, maxValue);
    ////            int[] arr2 = copyArray(arr1);
    ////            selectionSort(arr1);
    ////            selectionSort(arr1);
    ////            insertionSort(arr1);
    ////            comparator(arr2);
    ////            if (!isEqual(arr1, arr2)) {
    ////                succeed = false;
    ////                printArray(arr1);
    ////                printArray(arr2);
    ////                break;
    ////            }
    //
    //            //Test for nearestIndex
    //            int[] arr = generateRandomArray(maxSize, maxValue);
    //            Arrays.sort(arr);
    //            int value = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
    //            if (test(arr, value) != nearestIndex(arr, value)) {
    //                printArray(arr);
    //                System.out.println(value);
    //                System.out.println(test(arr, value));
    //                System.out.println(nearestIndex(arr, value));
    //                succeed = false;
    //                break;
    //            }
    //        }
    
    //        System.out.println(succeed ? "Nice!" : "Fucking fucked!");
    
    //        int[] arr = generateRandomArray(maxSize, maxValue);
    //        printArray(arr);
    //        selectionSort(arr);
    //        printArray(arr);
    
            //Test for printOddTimesNum1
    //        int[] arr1 = {3, 3, 2, 3, 1, 1, 1, 3, 1, 1, 1};
    //        printOddTimesNum1(arr1);
    
    //        int[] arr2 = {4, 3, 4, 2, 2, 2, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 2, 2};
    //        printOddTimesNum2(arr2);
    
            System.out.println(bit1counts(9));
        }
    
        // for test
        public static int test(int[] arr, int value) {
            for (int i = 0; i < arr.length; i++) {
                if (arr[i] >= value) {
                    return i;
                }
            }
            return -1;
        }
    
        // for test
        public 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;
            }
            for (int i = 0; i < arr1.length; i++) {
                if (arr1[i] != arr2[i]) {
                    return false;
                }
            }
            return true;
        }
    
        // for test
        public static int[] generateRandomArray(int maxSize, int maxValue) {
            /*
             * Math.random()    [0,1)
             * Math.random()*N    [0,N)
             * (int)(Math.random()*N)    [0,N-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;
        }
    
        // for test
        public static void comparator(int[] arr) {
            Arrays.sort(arr);
        }
    
        // for test
        public 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;
        }
    
        public static void swap(int[] arr, int i, int j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    
        //位运算交换数组arr[i]和arr[j]指向同一块内存时值为0
        public static void swapBitOperation(int[] arr, int i, int j) {
            arr[i] = arr[i] ^ arr[j];
            arr[j] = arr[i] ^ arr[j];
            arr[i] = arr[i] ^ arr[j];
        }
    
        public static void printArray(int[] arr) {
            if (arr == null) {
                return;
            }
            for (int i = 0; i < arr.length; i++) {
                System.out.println(arr[i] + "  ");
            }
            System.out.println();
        }
    }
    package arithmetic;

    import java.util.ArrayList;
    import java.util.Arrays;

    /**
    * @author hailu
    */
    public class Sort {
    /**
    * 选择排序
    */
    public static void selectionSort(int[] arr) {
    if (arr == null || arr.length < 2) {
    return;
    }
    /*
    * 0 ~ n-1
    * 1 ~ n-1
    * 2 ~ n-1
    * ...~ n-1
    * */
    // i ~ N-1
    for (int i = 0; i < arr.length - 1; i++) {
    // 最小值在哪个位置上 in-1
    int minIndex = i;
    // i ~ N-1 上找最小值的下标
    //从第二个开始,每个元素和左侧元素比较
    for (int j = i + 1; j < arr.length; j++) {
    minIndex = arr[j] < arr[minIndex] ? j : minIndex;
    }
    swap(arr, i, minIndex);
    }
    }

    /**
    * 冒泡排序
    */
    public static void bubbleSort(int[] arr) {
    if (arr == null || arr.length < 2) {
    return;
    }
    // 0 ~ N-1
    // 0 ~ N-2
    // 0 ~ N-3
    //从最后一个元素开始
    for (int i = arr.length - 1; i > 0; i--) {
    for (int j = 0; j < i; j++) {
    //从第一个元素开始,右侧相邻元素比较
    if (arr[j] < arr[i + 1]) {
    swap(arr, i, j + 1);
    }
    }
    }
    }

    /**
    * 插入排序
    */
    public static void insertionSort(int[] arr) {
    if (arr == null || arr.length < 2) {
    return;
    }
    // 0~0 是有序的
    // 0~i 想有序
    for (int i = 1; i < arr.length; i++) {
    for (int j = i; j > 0; j--) {
    if (arr[j] < arr[j - 1]) {
    swap(arr, j, j - 1);
    }
    }
    }
    }

    /**
    * 二分法:查找有序数组是否包含某个数字
    *
    * @param sortedArr
    * @param num
    * @return
    */
    public static boolean exist(int[] sortedArr, int num) {
    if (sortedArr == null || sortedArr.length == 0) {
    return false;
    }
    int L = 0;
    int R = sortedArr.length - 1;

    while (L < R) {
    // mid = (L+R) / 2;
    // L 10亿 R 18亿 超出int最大值
    // mid = L + (R - L) / 2
    // N / 2 N >> 1
    int mid = L + ((R - L) >> 1);
    if (sortedArr[mid] == num) {
    return true;
    } else if (sortedArr[mid] > num) {
    R = mid - 1;
    } else {
    L = mid + 1;
    }
    }
    return sortedArr[L] == num;
    }

    /**
    * 二分法:在arr上,找满足>=value的最左位置
    *
    * @param arr
    * @param value
    * @return
    */
    public static int nearestIndex(int[] arr, int value) {
    int L = 0;
    int R = arr.length - 1;
    int index = -1;
    while (L <= R) {
    int mid = L + ((R - L) >> 1);
    //这里的 >= 符号和题干对应
    if (arr[mid] >= value) {
    //更新index
    index = mid;
    R = mid - 1;
    } else {
    L = mid + 1;
    }
    }
    return index;
    }

    /**
    * arr中,只有一种数,出现奇数次
    *
    * @param arr
    */
    public static void printOddTimesNum1(int[] arr) {
    //0^N -> N
    int eor = 0;
    for (int i = 0; i < arr.length; i++) {
    //异或异或满足交换律结合律,偶数次按位异或后为0
    // eor=eor^arr[1];
    // eor=eor^arr[2];
    // eor=eor^arr[3];
    eor ^= arr[i];
    }
    System.out.println(eor);
    }

    //怎么把int数提取出最右侧的 1
    // N&((~N)+1)
    //N = 0000 1101 1000
    //~N= 1111 0010 0111
    //~N+1= 1111 0010 1000
    //N&((~N)+1)=0000 0000 1000 最右侧的 1 出现了

    /**
    * arr中有两种数出现了奇数次,其他数出现了偶数次,找到这两种数
    *
    * @param arr
    */
    public static void printOddTimesNum2(int[] arr) {
    //找到出现奇数次的两个数
    int eor = 0;
    for (int i = 0; i < arr.length; i++) {
    //偶数次最后位0
    // a!=b -> eor!=0
    // a b 存在第 n 位不相同,eor必然有一个位置上是1
    // eor最后的结果是 a^b
    // n 位存在两种数 0(有奇有偶) 1(有奇有偶),但是 a b 一定是分开的
    eor ^= arr[i];
    }
    // 提取出最右的 1 0000 0000 1000
    int rightOne = eor & ((~eor) + 1);
    //eor'
    int one = 0;
    for (int i = 0; i < arr.length; i++) {
    if ((arr[i] & rightOne) != 0) {
    // 或者 if ((arr[i] & rightOne) == rightOne) {

    // rightOne 0000 0001 0000
    //arr[i]&rightOne 0000 1011 0000
    //(arr[i]&rightOne)!=0 代表该位有 1
    //
    one ^= arr[i];
    }
    }
    int tow = eor ^ one;
    System.out.println(one + " " + tow);
    }

    /**
    * 任意数中二进制 1 的个数
    *
    * @param N
    * @return
    */
    public static int bit1counts(int num) {
    //方法1:循环32
    //方法2:比循环32次要快
    int count = 0;
    while (num != 0) {
    int rightOne = num & ((~num) + 1);
    count++;
    //抹掉最后一个 1
    num ^= rightOne;
    //num为正数时可这么写: num -= rightOne
    }
    return count;
    }

    public static void main(String[] args) {
    // int[] arr = new int[]{5, 3, 4, 1, 2};
    // int[] arr = new int[]{1, 2, 3, 4, 5};
    // System.out.println(nearestIndex(arr,4));
    //
    // selectionSort(arr);
    // boolean b=exist(arr,1);
    // printArray(arr);
    //
    // int testTime = 500000;
    // int maxSize = 100;
    // int maxValue = 100;
    // boolean succeed = true;
    // for (int i = 0; i < testTime; i++) {
    //// int[] arr1 = generateRandomArray(maxSize, maxValue);
    //// int[] arr2 = copyArray(arr1);
    //// selectionSort(arr1);
    //// selectionSort(arr1);
    //// insertionSort(arr1);
    //// comparator(arr2);
    //// if (!isEqual(arr1, arr2)) {
    //// succeed = false;
    //// printArray(arr1);
    //// printArray(arr2);
    //// break;
    //// }
    //
    // //Test for nearestIndex
    // int[] arr = generateRandomArray(maxSize, maxValue);
    // Arrays.sort(arr);
    // int value = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
    // if (test(arr, value) != nearestIndex(arr, value)) {
    // printArray(arr);
    // System.out.println(value);
    // System.out.println(test(arr, value));
    // System.out.println(nearestIndex(arr, value));
    // succeed = false;
    // break;
    // }
    // }

    // System.out.println(succeed ? "Nice!" : "Fucking fucked!");

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

    //Test for printOddTimesNum1
    // int[] arr1 = {3, 3, 2, 3, 1, 1, 1, 3, 1, 1, 1};
    // printOddTimesNum1(arr1);

    // int[] arr2 = {4, 3, 4, 2, 2, 2, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 2, 2};
    // printOddTimesNum2(arr2);

    System.out.println(bit1counts(9));
    }

    // for test
    public static int test(int[] arr, int value) {
    for (int i = 0; i < arr.length; i++) {
    if (arr[i] >= value) {
    return i;
    }
    }
    return -1;
    }

    // for test
    public 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;
    }
    for (int i = 0; i < arr1.length; i++) {
    if (arr1[i] != arr2[i]) {
    return false;
    }
    }
    return true;
    }

    // for test
    public static int[] generateRandomArray(int maxSize, int maxValue) {
    /*
    * Math.random() [0,1)
    * Math.random()*N [0,N)
    * (int)(Math.random()*N) [0,N-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;
    }

    // for test
    public static void comparator(int[] arr) {
    Arrays.sort(arr);
    }

    // for test
    public 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;
    }

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

    //位运算交换数组arr[i]arr[j]指向同一块内存时值为0
    public static void swapBitOperation(int[] arr, int i, int j) {
    arr[i] = arr[i] ^ arr[j];
    arr[j] = arr[i] ^ arr[j];
    arr[i] = arr[i] ^ arr[j];
    }

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


  • 相关阅读:
    如何用Java编写一段代码引发内存泄露
    获取一天的开始时间和结束时间
    servlet,jsp,tomcat,jdk对应版本关系,如何查看jsp和servlet版本信息
    什么是元数据?
    什么是Device ID?
    如何查看移动设备标识码
    手机wifi的mac地址是什么??
    MD5摘要
    落地页和离线广告
    广告行业一些常用物料的尺寸
  • 原文地址:https://www.cnblogs.com/yanghailu/p/12772148.html
Copyright © 2020-2023  润新知