zoukankan      html  css  js  c++  java
  • 选择、冒泡、插入排序,二分法和对数器

    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();
    }
    }


  • 相关阅读:
    Maven 集成Tomcat插件
    dubbo 序列化 问题 属性值 丢失 ArrayList 解决
    docker 中安装 FastDFS 总结
    docker 从容器中拷文件到宿主机器中
    db2 相关命令
    Webphere WAS 启动
    CKEDITOR 4.6.X 版本 插件 弹出对话框 Dialog中 表格 Table 自定义样式Style 问题
    SpringMVC JSONP JSON支持
    CKEDITOR 3.4.2中 按钮事件中 动态改变图标和title 获取按钮
    git回退到远程某个版本
  • 原文地址:https://www.cnblogs.com/yanghailu/p/12772148.html
Copyright © 2011-2022 走看看