数据结构与算法(九)查找 - 二分查找

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

 

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