數據結構與算法(九)查找 - 二分查找

1.時間複雜度:logn

每次查找後,數據規模縮減爲原來的一半

2.代碼實現

@Test
    public void test() {
        System.out.println("========" + bsearch(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 9));
        bsearch2(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 9);
    }

    //非遞歸實現
    public int bsearch(int[] array, int target) {

        int low = 0;
        int heigh = array.length - 1;

        while (low <= heigh) {
            int mid = (low + heigh) / 2;

            if (array[mid] == target) return mid;
            else if (array[mid] > target) {
                heigh = mid - 1;
            } else {
                low = mid + 1;
            }
        }
        return -1;

    }

    //遞歸實現
    public void bsearch2(int[] array, int target) {
        System.out.println("-------" + realSearch(array, array.length - 1, 0, target));
    }

    public int realSearch(int[] array, int heigh, int low, int target) {
        if (low > heigh) return -1;
        int mid = low + ((heigh - low) >> 1);
        if (array[mid] == target) return mid;
        else if (array[mid] > target) {
            return realSearch(array, mid - 1, low, target);
        } else {
            return realSearch(array, heigh, mid + 1, target);
        }

    }

3.適用範圍

(1)查找依賴順序表結構,即數組

(2)需要數組是有序狀態

(3)數據量不能太大或者太小:因爲數組需要連續空間,太大的數據量一次性載入內存有風險;太小的數據量沒有時間上的優勢

4.拓展-變體問題

    @Test
    public void test() {
//        System.out.println("========" + bsearch(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 9));
//        bsearch2(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 9);

        System.out.println("first target = " + firstTarget(new int[]{1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10}, 9));
        System.out.println("last target = " + lastTarget(new int[]{1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10}, 9));
        System.out.println("firstTargetBig target = " + firstTargetBig(new int[]{1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10}, 6));
        System.out.println("lastTargetSmall target = " + lastTargetSmall(new int[]{1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10}, 9));
    }

    //查找第一個值等於給定值的元素
    public int firstTarget(int[] array, int target) {
        int low = 0;
        int heigh = array.length - 1;
        while (low <= heigh) {
            int mid = low + ((heigh - low) >> 1);
            if (array[mid] > target) {
                heigh = mid - 1;
            } else if (array[mid] < target) {
                low = mid + 1;
            } else {
                if (mid == 0 || array[mid - 1] != target)
                    return mid;
                else
                    heigh = mid - 1;
            }
        }
        return -1;
    }

    //查找最後一個值等於給定元素的值
    public int lastTarget(int[] array, int target) {
        int low = 0;
        int heigh = array.length - 1;
        while (low <= heigh) {
            int mid = low + ((heigh - low) >> 1);
            if (array[mid] > target) {
                heigh = mid - 1;
            } else if (array[mid] < target) {
                low = mid + 1;
            } else {
                if (mid == array.length - 1 || array[mid + 1] != target) {
                    return mid;
                } else {
                    low = mid + 1;
                }
            }
        }
        return -1;
    }

    //查找第一個大於等於給定值的元素
    public int firstTargetBig(int[] array, int target) {
        int low = 0;
        int heigh = array.length - 1;

        while (low <= heigh) {
            int mid = low + ((heigh - low) >> 1);

            if (array[mid] >= target) {
                if (mid == 0 || array[mid - 1] < target) {
                    return mid;
                } else {
                    heigh = mid - 1;
                }
            } else {
                low = mid + 1;
            }
        }
        return -1;
    }

    //查找最後一個小於等於給定值的元素
    public int lastTargetSmall(int[] array, int target) {
        int low = 0;
        int heigh = array.length - 1;

        while (low <= heigh) {
            int mid = low + ((heigh - low) >> 1);
            if (array[mid] > target) {
                heigh = mid - 1;
            } else {
                if ((mid == array.length - 1) || array[mid + 1] > target) {
                    return mid;
                } else {
                    low = mid + 1;
                }
            }
        }
        return -1;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章