日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

二分查找(Java实现)

發布時間:2024/1/3 综合教程 22 生活家
生活随笔 收集整理的這篇文章主要介紹了 二分查找(Java实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

二分查找:遞歸實現

public class BinarySearch {
    /**
     * @param arr    代查找的數組,需要有序
     * @param left   查找區間的左界限
     * @param right  查找區間的右界限
     * @param target 待查找的值
     * @param <T>    泛型
     * @return <p>在arr中[left...right]左閉右閉區間查找target, 找到了就返回該下角標,沒找到則返回-1.<p/>
     */
    public static <T extends Comparable<? super T>> int search(T[] arr, int left, int right, T target) {
        if (left > right) return -1;//遞歸結束了都沒找到,返回-1.

        int mid = left + (right - left) / 2; // 二分,arr[mid]作為比較的基準值。

        if (arr[mid].compareTo(target) == 0) {//如果相等,說明找到
            return mid;
        } else if (arr[mid].compareTo(target) < 0) {//如果中間的比target小,則在右半邊找
            return search(arr, mid + 1, right, target);
        } else {////如果中間的比target大,則在左半邊找
            return search(arr, left, mid - 1, target);
        }
    }

    public static <T extends Comparable<? super T>> int search(T[] arr, T target) {
        return search(arr, 0, arr.length - 1, target);
    }

    public static void main(String[] args) {
        Integer[] arr = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};//二分查找需要是有序的數組
        int ret = search(arr, 11);
        System.out.printf("下角標是:%d\n", ret);
    }
}  

二分查找:非遞歸實現

public class BinarySearch {
    public static <T extends Comparable<? super T>> int search(T[] arr, T target) {
        int left = 0;
        int right = arr.length - 1;
        while (left <= right) {//從[left ... right] 左閉右閉區間找,當left==right時,就是在判斷arr[left]是否等于target
            int mid = left + (right - left) / 2;
            if (arr[mid].compareTo(target) < 0) {//如果中間的比target還小,那么到右半邊去找
                left = mid + 1;
            } else if (arr[mid].compareTo(target) > 0) {//如果中間的比target大,那么到左半邊去找
                right = mid - 1;
            } else {//如果 arr[mid] == target
                return mid;
            }
        }
        //如果沒找到
        return -1;
    }

    public static void main(String[] args) {
        Integer[] arr = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};//二分查找需要是有序的數組
        int ret = search(arr, 11);
        System.out.printf("下角標是:%d\n", ret);
    }
}  

二分查找:求mid時除以2的bug問題

比如left = 1256648431, right = 1742321453 那么相加后就會上溢,得到結果 -1295997412,除以2之后就是-647998706,顯然這個結果是不對的。

下面介紹三種方法,可以計算出正確的結果 1499484942

public class BinarySearch {
    public static void main(String[] args) {
        int a = 1256648431;
        int b = 1742321453;
        long c = (long) a + b;

        System.out.printf("a + b 應該等于 %d        ", c);//a + b 應該等于 2998969884 ,正確
        System.out.printf("(a + b)/2 應該等于 %d\n\n", c / 2);//(a + b)/2 應該等于 1499484942 ,正確

        System.out.println("整數int型用普通除法");
        System.out.printf("a + b 等于 %d        ", a + b);// -1295997412 ,溢出
        System.out.printf("(a + b)/2 等于 %d\n\n", (a + b) / 2);// -647998706 ,溢出

        System.out.println("整數int型用邏輯右移代替除法");
        System.out.printf("a + b 等于 %d        ", a + b);// -1295997412 ,溢出
        System.out.printf("(a + b)>>>1 等于 %d\n\n", (a + b) >>> 1);// 1499484942 ,正確

        System.out.println("整數int型用位運算技巧代替除法");
        System.out.printf("a + b 等于 %d        ", a + b);// -1295997412 ,溢出
        System.out.printf("(a & b) + (a ^ b) >> 1 等于 %d\n\n", (a & b) + ((a ^ b) >> 1));// 1499484942 ,正確
    }
}

最后一種情況,請查看該博客:用位運算求兩個整型數的平均值(避免溢出)

給女朋友講最后一種情況時的筆記:

目的:兩個二進制數,對應位置進行相加,求出每項的項系數,也就是每位結果。
根據規律,分為兩種情況。
1.對應位不同,其中一個為1,另一個為0 2.對應位相同,即同為1,或同為0 設a:1100110,b:1010101. 那么a + b = 2110211.(先不考慮進位) 處理情況1:去找規律,發現,情況為1時,相加總為1,相當于異或運算。對于情況2,異或運算總為0,不會被影響到。 處理情況2:再去找規律,發現,情況為2時,兩數相加的結果要么是0,要么是2。結果總是‘&運算’結果的2倍。對于情況1,&運算結果總得到0,不會被影響到。 a:1100110 b:1010101 a^b:0110011 0 1 4 5 找到了這些項的系數 a&b:1000100 2 3 6 找到了這些項的系數 但上面這個與運算得出來的并不是真正的項系數,而是對應位置項系數的一般。所以 * 2后得 :2000200(先不考慮進位) 所以sum = (a & b) * 2 + (a ^ b) sum / 2 = (a & b) + (a ^ b) / 2 (后續再把這個除法改成右移運算) ---------------------------------------------------------- 或者換一種說法。 設a:1100110,b:1010101. 那么a + b = 2110211.(先不考慮進位) 對于a + b = 2110211.其中的2都是'&運算' 乘2得來,其中的1都是‘ ^運算 ’得來。

  

---------------------------------------------------------
學如不及,猶恐失之

總結

以上是生活随笔為你收集整理的二分查找(Java实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。