탐색 범위를 반으로 나누어서 찾는 값을 포함하는 범위를 좁혀나가는 방식의 알고리즘이다
주로 오름차순으로 정렬되어 있는 상태에서 사용해야한다
#include <iostream>
#define SIZE 8
using namespace std;
void BinarySearch(int list[], int key)
{
int left = 0;
int right = SIZE - 1;
while (left <= right)
{
int pivot = (left + right) / 2;
if (key == list[pivot])
{
cout << "Key Found : " << list[pivot];
return;
}
else if (key > list[pivot])
{
left = pivot + 1;
}
else if (key < list[pivot])
{
right = pivot - 1;
}
}
cout << "Not Key Found" << endl;
}
// 재귀사용방식
int main()
{
#pragma region 이진 탐색
// right < left면 값을 못찾은 상태 (엇갈림)
int list[SIZE] = { 1,2,30, 42,50, 55, 60,70 };
BinarySearch(list, 30);
#pragma endregion
return 0;
}

만약 내가 원하는 key값을 이 조건이 종료될 때까지 발견 못할 경우를 예로 들어보자
위와 같은 배열에서 찾고자 하는 key값을 65로 설정

pivot과 key값을 비교하며 left와 right의 위치를 이동
left와 right의 위치가 같아졌고 pivot의 위치도 같아졌을때, right와 left가 엇갈리는 경우가 있다
-> 이 경우는 key값이 없기때문

현재 경우는 pivot이 key값보다 작은 경우이고, 반대로 pivot이 key값보다 큰 경우는 오른쪽 범위에서 비슷하게 작동한다
#include <iostream>
using namespace std;
#define SIZE 8
// 이진탐색
// 배열의 크기는 8
// 오름차순 정렬로 되어있는 상태로 탐색
//
// 매개변수로 배열과 찾고자 하는 key값을 받는다
// 1. 반복문 사용방식
void BinarySearch(int list[], int key)
{
int left = 0;
int right = SIZE - 1;
while (left <= right)
{
int pivot = (left + right) / 2;
// 키 찾으면 바로 종료
if (key == list[pivot])
{
cout << "Key Found : " << list[pivot] << endl;
return;
}
else if (key > list[pivot])
{
left = pivot + 1;
}
else if (key < list[pivot])
{
right = pivot - 1;
}
}
// 반복문이 종료되어도 찾지 못했으면 찾는key값이 없는 것
cout << "Not Key Found" << endl;
}
int main()
{
int list[SIZE] = { 1,2,30, 42,50, 55, 60,70 };
BinarySearch(list, 30);
return 0;
}


#include <iostream>
using namespace std;
#define SIZE 8
// 이진탐색
// 배열의 크기는 8
// 오름차순 정렬로 되어있는 상태로 탐색
//
// 매개변수로 배열과 찾고자 하는 key값을 받는다
// 2. 재귀 사용방식
void BinarySearch(int list[], int key, int left, int right)
{
// 함수 종료
if (left > right)
{
// 찾는key값이 없는 것
cout << "Not Key Found" << endl;
return;
}
int pivot = (left + right) / 2;
// 키 찾으면 바로 종료
if (key == list[pivot])
{
cout << "Key Found : " << list[pivot] << endl;
return;
}
else if (key > list[pivot])
{
left = pivot + 1;
BinarySearch(list, key, left, right);
}
else if (key < list[pivot])
{
right = pivot - 1;
BinarySearch(list, key, left, right);
}
}
int main()
{
int list[SIZE] = { 1,2,30, 42,50, 55, 60,70 };
int left = 0;
int right = SIZE - 1;
BinarySearch(list, 30, left, right);
return 0;
}
시간복잡도 O(logN)
-> 탐색범위가 N/2, N/4, N/8씩 반으로 줄어들기 때문이다
혹시나 잊어버릴까봐 다시 정리
-> 이진탐색은 탐색범위를 반씩 줄여나간다 (깊이가 logN이 되는 것)
-> 나머지 반은 탐색하지 않는다 (연산도 logN이 되는 것)
예를 들어, 배열의 크기가 8이면 3단계에 걸쳐 크기가 1이 된다
즉, log₂8 = 3 이다
컴퓨터 과학에서 O(logN)은 O(log₂N)을 줄여서 부르는 말이다
자세한 건 시간복잡도 포스트에 설명되어있다 (보고오자)
