二分查找、upper_bound、lower_bound

整理及总结二分查找的判断和边界细节

修改版

package com.leej.binarysearch;

import java.util.Arrays;

/**
 * @author jerry
 * @create 17/10/7 12:21
 */
public class BinarySearch {

    public static int BinarySearch(int[] nums, int key) {
        int start = 0, end = nums.length - 1;
        int mid;
        while(start <= end) {
            mid = (start + end) >> 1;
            if (nums[mid] == key) return mid;
            else if (nums[mid] > key)
                end = mid -1;
            else
                start = mid + 1;
        }
        return -(start + 1);
    }

    public static int LowerBound(int[] nums, int key) {
        int first = 0, last = nums.length;
        int mid;
        while(first < last) {
            mid = (first + last) >> 1;
            if (nums[mid] < key) {
                first = mid + 1;
            } else {
                last = mid;
            }
        }
        return first;
    }

    public static int UpperBound(int[] nums, int key) {
        int first = 0, last = nums.length;
        int mid;
        while(first < last) {
            mid = (first + last) >> 1;
            if (nums[mid] <= key) {
                first = mid + 1;
            } else {
                last = mid;
            }
        }
        return first;
    }

    public static void showArrays(int[] nums) {
        for(int num : nums) System.out.print(num + " ");
        System.out.println();

    }
    public static void main(String[] args) {
        int[] nums = {10,20,30,30,20,10,10,20, 10};
        Arrays.sort(nums); //10 10 10 20 20 20 30 30
        showArrays(nums);
        //System.out.println( BinarySearch(nums, 11) );
        System.out.println(LowerBound(nums, 21));
        System.out.println(UpperBound(nums, 21));
    }
}

实现

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Arrays;
import java.lang.String;
/**
 * @author jerry
 * @create 
 */
public class test {
	public static void showArray(int[] nums) {
		if (nums == null || nums.length == 0) return;

		for (int nu : nums) 
			System.out.printf("%d ", nu);
		System.out.println();
	}

	/**
	* 循环条件left<=right, 所以left != mid , right != mid;
	* 双闭区间[left, right]
	**/
	public static int binarySearch(int[] nums, int target) {
		int left = 0, right = nums.length - 1, mid; //search range [left, right],闭区间
		while(left <= right) {
			mid = (left + right) >> 1;
			if (nums[mid] == target)
				return mid;
			else if (nums[mid] < target)
				left = mid + 1;
			else
				right = mid - 1;
		}
		return -1;
	}

	/**
	**STL 版本lower_bound
	* 找到第一个大于等于target的数, in range [first, last), 左开右闭区间
	**/
	public static int lower_bound(int[] nums, int target) {
		int first = 0, last = nums.length;
		int mid, len, step;
		len = last - first;
		while(len > 0) {
			step = len >> 1;
			mid = first + step;
			if (nums[mid] < target) { //[mid + 1, last)
				first = mid + 1;
				len -= step + 1;
			} else { //[first, mid)最后可取边界mid
				len = step;
			}
		}
		return first;
	}

	//找到第一个大于等于target
	public static int my_lower_bound(int[] nums, int target) {
		int first = 0, last = nums.length, mid;
		//in ranget [first, last)
		while(first < last) {
			mid = (first + last) >> 1;
			if (nums[mid] < target) { //[mid+1, last)
				first = mid + 1;
			} else {
				last = mid;
			}
		}
		return first;
	}

	//找到第一个大于target的数
	public static int my_upper_bound(int[] nums, int target) {
		int first = 0, last = nums.length, mid;
		//in range [first, last)
		while(first < last) {
			mid = (first + last) >> 1;
			if (nums[mid] <= target) { 
				first = mid + 1;
			} else {
				last = mid;
			}
		}
		return first;
	}

	public static void main( String args[] ){
		int[] nums = {10,20,30,30,20,10,10,20, 10};
		Arrays.sort(nums); //10 10 10 20 20 20 30 30
		test.showArray(nums);
		System.out.println( test.binarySearch(nums, 11) );
		System.out.println( test.my_lower_bound(nums, 20) );
		System.out.println( test.lower_bound(nums, 20) );
		System.out.println( test.my_upper_bound(nums, 20) );
	}
}

//#output
// 10 10 10 10 20 20 20 30 30
// -1
// 4
// 4
// 7


References

  1. http://www.cplusplus.com/reference/algorithm/lower_bound/
  2. http://www.cplusplus.com/reference/algorithm/upper_bound/
  3. http://www.cplusplus.com/reference/algorithm/binary_search/
posted @ 2017-06-02 14:45  一弓一土两亩田  阅读(236)  评论(0编辑  收藏  举报