이분 탐색 알고리즘 구현

  • 6 minutes to read

개요

이분 탐색(Binary Search)은 정렬된 배열에서 특정 요소를 효율적으로 찾는 알고리즘입니다. 이 예제에서는 C 언어를 사용하여 이분 탐색을 구현합니다. 파일명 binary_search_impl.c는 "Binary Search Implementation"을 의미합니다.

코드 설명

이 예제의 주요 구성 요소는 다음과 같습니다:

  1. 정렬된 데이터 배열: 이분 탐색은 데이터가 정렬되어 있을 때만 효과적입니다. 여기서는 간단한 정수 배열 sortedArray를 사용합니다.
  2. 사용자 입력 처리: 사용자로부터 찾고자 하는 키(key)를 입력받습니다. 입력이 유효하지 않을 경우, 프로그램은 오류 메시지를 출력하고 종료됩니다.
  3. 이분 탐색 알고리즘:
    • lowhigh 변수는 탐색 범위를 나타냅니다. 초기에는 전체 배열을 대상으로 합니다.
    • mid 변수는 현재 탐색 범위의 중간점을 나타냅니다. 이는 lowhigh를 이용하여 계산됩니다.
    • 배열의 mid 인덱스에 위치한 값이 key와 일치하는지 확인합니다.
    • 일치하지 않는 경우, key가 중간점의 값보다 크면 low를 조정하고, 작으면 high를 조정하여 탐색 범위를 절반으로 줄입니다.
  4. 결과 출력: 찾는 값이 배열에 있으면 그 위치를 출력하고, 없으면 "찾을 수 없습니다."라는 메시지를 출력합니다.

코드

코드: binary_search_impl.c

#include <stdio.h>

#define N 5 // 정렬된 데이터의 수

int main(void)
{
    int sortedArray[] = { 21, 33, 35, 47, 59 }; // 정렬된 데이터 배열
    int key; // 사용자로부터 입력받을 검색 키
    int low = 0; // 검색 범위의 시작 인덱스
    int high = N - 1; // 검색 범위의 끝 인덱스
    int mid; // 검색 범위의 중간 인덱스
    int flag = 0; // 검색 성공 여부 플래그

    printf("탐색할 데이터: ");
    if (scanf("%d", &key) != 1)
    {
        printf("올바른 숫자를 입력하세요.\n");
        return 1;
    }

    while (low <= high)
    {
        mid = low + (high - low) / 2; // 중간 인덱스 계산 (오버플로 방지)

        if (sortedArray[mid] == key)
        {
            printf("%d는 %d번째에 있습니다.\n", key, mid + 1);
            flag = 1;
            break;
        }
        else if (sortedArray[mid] < key)
        {
            low = mid + 1; // 검색 범위를 상위 절반으로 조정
        }
        else
        {
            high = mid - 1; // 검색 범위를 하위 절반으로 조정
        }
    }

    if (!flag)
    {
        printf("찾을 수 없습니다.\n");
    }

    return 0;
}

오버플로 방지를 위한 중간 인덱스 계산

정수 오버플로란?

정수 오버플로는 프로그램이 표현할 수 있는 정수의 최대 범위를 초과할 때 발생합니다. 예를 들어, 32비트 정수에서는 -2,147,483,648부터 2,147,483,647까지의 값을 표현할 수 있습니다. 이 범위를 넘어서는 값을 계산하려고 하면 오버플로가 발생하여 예상치 못한 결과를 초래할 수 있습니다.

오버플로 방지를 위한 중간 인덱스 계산

전통적인 이분 탐색 알고리즘에서 중간 인덱스는 (low + high) / 2로 계산되곤 합니다. 그러나 lowhigh가 모두 큰 양의 정수일 경우, 이들의 합은 오버플로를 일으킬 수 있습니다. 예를 들어, 두 정수가 모두 2,147,483,647에 가깝다면, 그 합은 4,294,967,294가 되어 32비트 정수 범위를 초과합니다.

이 문제를 해결하기 위해 mid = low + (high - low) / 2; 식을 사용합니다. 이 방식은 다음과 같은 이유로 오버플로를 방지합니다:

  • high - low는 항상 high보다 작거나 같습니다. 따라서 이 차이는 음수가 되지 않으며, 오버플로를 일으키지 않습니다.
  • low + (high - low) / 2lowhigh의 중간 값을 나타내므로, 이 값 역시 high를 초과할 수 없습니다.

결론

따라서, 이 방식은 lowhigh가 모두 큰 값을 가질 때도 안전하게 중간 값을 계산할 수 있게 해줍니다. 이는 특히 큰 데이터셋을 다룰 때 중요한 고려사항이 됩니다. 이러한 방식으로 오버플로를 방지하면, 이분 탐색 알고리즘이 더 안정적으로 작동하게 됩니다.

결론

이 예제는 C 언어를 이용한 기본적인 이분 탐색 알고리즘의 구현을 보여줍니다. 정렬된 배열에서 효율적으로 요소를 찾는 방법을 이해하는 데 도움이 됩니다.

VisualAcademy Docs의 모든 콘텐츠, 이미지, 동영상의 저작권은 박용준에게 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다. 사이트의 콘텐츠를 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다. 단, 링크와 SNS 공유, Youtube 동영상 공유는 허용합니다. www.VisualAcademy.com
박용준 강사의 모든 동영상 강의는 데브렉에서 독점으로 제공됩니다. www.devlec.com