• 二分查找、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/
  • 相关阅读:
    PHP分页类
    phpexcel 控制导出数据内容和行数
    phpexcel 导入 和 导出
    PHP无限极分类
    php 对查询结果集进行排序
    php 删除文件夹及文件夹内文件函数
    php 字符串截取函数
    php 获取用户登录的ip
    js layer页面层加载新网站
    分享到qq
  • 原文地址:https://www.cnblogs.com/johnleo/p/binary_search.html
Copyright © 2020-2023  润新知