이진 탐색 (Binary Search)

※ Data가 정렬이 되어 있어야 한다!

  • 일반적 구현

	public static int binarySearch(int[] arr, int target) {
		int left = 0;
		int right = arr.length - 1;
		int mid = 0;
		
		while(left <= right) {
			mid = (left + right) / 2;
			
			if(arr[mid] < target)
				left = mid + 1;
			else if (arr[mid] > target)
				right = mid - 1;
			else
				return mid;
		}
		
		return Integer.MIN_VALUE;
	}

  • 재귀적 구현

	public static int binarySearchRecursive(int[] arr, int target, int left, int right) {
		if(left > right)
			return Integer.MIN_VALUE;
		
		int mid = (left + right) / 2;
		if(arr[mid] < target)
			return binarySearchRecursive(arr, target, left + 1, right);
		else if (arr[mid] > target)
			return binarySearchRecursive(arr, target, left, right - 1);
		else
			return mid;
	}

Interpolation Search (보간 탐색)

중간부터 찾지 말고, 실제 값이 있는 위치부터 찾기!

  • 일반적 구현

	public static int interpolationSearch(int[] arr, int target) {
		int left = 0;
		int right = arr.length - 1;
		int mid = 0;
		
		int count = 0;
		
		while(left <= right) {
			mid = (int)(((double)target - arr[left]) / (arr[right] - arr[left]) * (right - left) + left);
			
			if(arr[mid] < target)
				left = mid + 1;
			else if (arr[mid] > target)
				right = mid - 1;
			else {
				System.out.println(count);
				return mid;
			}
			
			count++;
		}
		
		return Integer.MIN_VALUE;
	}

  • 재귀적 구현

	public static int interpolationSearchRecursive(int[] arr, int target, int left, int right) {
		if(arr[left] > target || arr[right] < target) // 값의 범위를 넘어서는 경우 있음.
			return Integer.MIN_VALUE;
		
		int mid = (int)(((double)target - arr[left]) / (arr[right] - arr[left]) * (right - left) + left);
		
		if(arr[mid] < target)
			return interpolationSearchRecursive(arr, target, left + 1, right);
		else if (arr[mid] > target)
			return interpolationSearchRecursive(arr, target, left, right - 1);
		else
			return mid;
	}

  • A < X ≤ B 조건을 검색. (반환값이 index+1 이므로)
첫번째 값을 찾지 못하는 Bug 있음.

	// 보간탐색을 이용한 근사값 찾기
	public static int interpolationSearch(char[] arr, int left, int right, int target) {
	    int mid = 0;
	     
	    while(left <= right) {
	        mid = (int)(((double)target - arr[left]) / (arr[right] - arr[left]) * (right - left) + left);

	        // index가 left보다 크고, right보다 작을 때
	        if(mid > left && mid < right) {
	        	if(arr[mid - 1] < target && target <= arr[mid]) {
	        		return mid + 1;
	        	}
	        }
	        else if (mid == left) {
	        	return left + 1;
	        }
	        else
	        	return Integer.MIN_VALUE;

	        
	        if(arr[mid] < target)
	            left = mid + 1;
	        else if (arr[mid] > target)
	            right = mid - 1;
	    }
	     
	    return Integer.MIN_VALUE;
	}

algorithm/binary_search.txt · Last modified: 2021/02/07 03:15 by 127.0.0.1