Fork me on GitHub

数据结构——二分搜索

递归实现

时间、空间复杂度均为 O(logN)

/**
 * 二分搜索(递归实现)
 * @param A     待搜索数组
 * @param num   搜索值
 * @param left  区间左指针
 * @param right 区间右指针
 * @param mid   基准
 */
private static void search(int[] A, int num, int left, int right, int mid) {
    if (A[mid] == num) { // 如果找到要找的数,记录其下标
        res = mid;
    }
    if (left >= right)
        return ;
    if (A[mid] >= num) { // 出现在左边
        right = mid - 1;
        mid = left + (right-left)/2;
        search(A, num, left, right, mid);
    }
    if (A[mid] < num) { // 出现在右边
        left = mid + 1;
        mid = left + (right-left)/2;
        search(A, num, left, right, mid);
    }
}

非递归实现

时间复杂度为 O(logN),空间复杂度为 O(1)

/**
 * 二分搜索(非递归实现)
 * @param A     带搜索数组
 * @param n     数组长度
 * @param num   搜索值
 * @return
 */
private static int search2(int[] A, int n, int num) {
    int left = 0;
    int right = n - 1;
    int res = -1;
    while (left <= right) {
        int mid = left + (right - left)/2;
        if (A[mid] == num) {
            res = mid;
            right = mid - 1;
        }
        if (A[mid] >= num) { // 左区间
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return res;
}

private static int search3(int[] arr, int n, int num) {
    int left = 0;
    int right = n-1;
    while (left <= right) {
        int mid = left + ((right-left)>>1);
        if (arr[mid] > num) {
            right = mid-1;
        }else if (arr[mid] < num) {
            left = mid+1;
        }else {
            return mid;
        }
    }
    return -1;
}

简单应用:在有序数组中查找某数 num 的出现次数 m

给定数组 arr 和要找的数为 num。

首先确定 num 最左出现的下标位置,记为 indexL,再确定 num 在数组中最右出现的下标位置,记为 indexR。

比如 arr = {0,1,1,2,3,3,3,4}

当 num = 1 时,indexL = 1,indexR = 2,出现次数 m = indexR - indexL + 1;

当 num = 2 时,indexL = 3,indexR = 3,m = 1,因为 indexL == indexR;

当 num = 4 时,indexL = 7,indexR = 7;m = 1;

/**
 * Created by zhengbinMac on 2017/4/11.
 */
public class Search {
    public static void main(String[] args) {
        int[] arr = {0, 1, 1, 2, 3, 3, 3, 4};
        int m = search(arr, 3);
        System.out.println(m);
    }
    private static int search(int[] arr, int num) {
        int indexL = 0;
        int indexR = 0;
        int left = 0;
        int right = arr.length - 1;
        // 找到数组中为 num 的最左下标位置
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            if (arr[mid] > num) {
                right = mid - 1;
            }else if (arr[mid] < num) {
                left = mid + 1;
            }else {
                right = mid - 1;
                indexL = mid;
            }
        }
        left = 0;
        right = arr.length - 1;
        // 找到数组中为 num 的最右下标位置
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            if (arr[mid] > num) {
                right = mid - 1;
            }else if (arr[mid] < num) {
                left = mid + 1;
            }else {
                left = mid + 1;
                indexR = mid;
            }
        }
        if (indexR == indexL) {
            return 1;
        }else {
            return indexR - indexL + 1;
        }
    }
}

 

posted @ 2017-03-22 23:41  郑斌blog  阅读(1024)  评论(0编辑  收藏  举报