일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 추천
- 넥스트에디션 2호점
- 2021 방탈출 추천
- 넥스트에디션
- 홍대 방탈출 추천
- 공포 방탈출
- C++ 자료구조
- 개발
- 윈도우 프로그래밍
- Android
- 방탈출 후기
- 후기
- 정렬 알고리즘
- Unity
- C 자료구조
- 방탈출 추천
- 방탈출 리뷰
- PC VR
- 홍대 방탈출
- 이스케이퍼스 2호점
- 유니티
- 필활
- 강남 방탈출
- 꽃길
- 방탈출
- 홍대 덤앤더머
- 홍대
- 이스케이퍼스
- C#
- 시스템 프로그래밍
- Today
- Total
행복한 연어의 이야기
(C/C++) 검색 - 이분 탐색, 이진 탐색 (Binary Search), 보간탐색(Interpolation Search) 본문
(C/C++) 검색 - 이분 탐색, 이진 탐색 (Binary Search), 보간탐색(Interpolation Search)
해피살몬 2021. 5. 26. 19:11검색 알고리즘은 검색 로직뿐만 아니라 삽입 삭제 로직도 같이 구현했습니다.
1. 이분 탐색, 이진 탐색 (Binary Search)
평균적으로 log²N 의 검색길이를 갖는 빠른 검색방법입니다.
다만 이분검색은 데이터들이 정렬되어 있어야 합니다.
또한 검색은 쉬운데 삽입 삭제가 조금 까다롭다고 생각하시면 됩니다.
즉 삽입 삭제가 빈번이 일어나는 데이터보다 검색만을 위한 데이터를 위해 사용하는게 좋습니다.
2. 구현 방법
이미 정렬된 데이터 집합에 중간값과 내 키의 값을 비교하여 왼쪽 혹은 오른쪽 구간을 선택,
그 구간의 중간값과 키값을 비교 하는 재귀적인 과정을 통해 검색이 완료됩니다.
검색은 중간값과 키값이 일치할떄까지 구간을 반으로 나누는 작업을 진행하며 키값을 찾습니다.
삽입은 어느위치에 넣어야 정렬이 유지되는지 위치를 찾고 그 위치로부터 한칸씩 뒤로 밀고 삽입합니다.
삭제는 삭제할 키의 위치를 찾고 한칸씩 앞으로 당깁니다.
3. 배열을 이용한 이진 탐색 구현
struct Data
{
int key;
int phone;
};
class BinaryArray
{
private:
Data* arrays;
int maxCnt;
int currentCnt;
bool FineIndex(int key, int& index);
public:
BinaryArray(int max = 100);
~BinaryArray();
bool Search(int key, Data& data);
bool Insert(Data data);
bool Delete(int key);
void PrintAll();
};
이진 탐색의 헤더 입니다.
Data 구조체를 선언했고 내부 연산에 필요한 FindIndex 함수를 Private 로 선언했습니다.
#include "BinaryArray.h"
#include <stdio.h>
bool BinaryArray::FineIndex(int key, int& index)
{
int mid;
int left = 0;
int right = currentCnt;
while (left <= right)
{
mid = (left + right) / 2;
if (arrays[mid].key == key)
{
index = mid;
return true;
}
else if (arrays[mid].key < key) //mid index에 있는 값이 찾는값보다 작으면 오른쪽에서 찾는다.
left = mid + 1;
else if (arrays[mid].key > key) //mid index에 있는 값이 찾는값보다 크면 왼쪽에서 찾는다.
right = mid - 1;
}
return false;
}
BinaryArray::BinaryArray(int max)
{
maxCnt = max;
currentCnt = 0;
arrays = new Data[maxCnt];
}
BinaryArray::~BinaryArray()
{
delete[] arrays;
}
bool BinaryArray::Search(int key, Data& data)
{
int index;
if (FineIndex(key, index))
{
data = arrays[index];
return true;
}
return false;
}
bool BinaryArray::Insert(Data data)
{
if (currentCnt >= maxCnt)
return false;
int index = 0;
while (data.key > arrays[index].key && index < currentCnt) //오름차순으로 넣는다.
index++;
for (int i = currentCnt; i > index; i--)
{
arrays[i] = arrays[i - 1];
}
arrays[index] = data;
currentCnt++;
return true;
}
bool BinaryArray::Delete(int key)
{
int index;
if (FineIndex(key, index))
{
for (int i = index + 1; i < currentCnt; i++)
{
arrays[i - 1] = arrays[i];
}
currentCnt--;
return true;
}
return false;
}
void BinaryArray::PrintAll()
{
for (int i = 0; i < currentCnt; i++)
{
printf("key : %d\tPhone : %d\n", arrays[i].key, arrays[i].phone);
}
}
이진 탐색의 CPP 입니다.
오름차순으로 정렬을 했고(작은 값이 앞으로) 그에 맞춰 검색을 하고 있습니다.
삽입시 뒤로, 삭제시 앞으로 배열을 이동해 주었습니다.
4. 이진 탐색의 개선 보간 탐색 (Interpolation Search)
이진 탐색을 할 데이터들이 고르게 분포되어 있다면 보간탐색을 사용하는 것이 더 짧은 평균 탐색 시간을 가집니다.
반대로 고르지 못한 데이터들을 검색한다면 시간이 좀 더 걸릴 수 있습니다.
위 이진 탐색에서 실질적으로 탐색하는 부분인 FineIndex 함수를 수정만 하면 됩니다.
이진 탐색이랑 가장 큰 차이점은 이진 탐색은 데이터들의 중간 값 mid 를 찾아 줄여 나가는 것이고
보간 탐색은 mid 가 아니고 찾는 값이 상대적으로 작다면 앞쪽에서, 크다면 뒤쪽에서 찾아 줄여나가는 방식입니다.
bool BinaryArray::FineIndex(int key, int& index)
{
int findIndex;
int left = 0;
int right = currentCnt;
while (left <= right)
{
if (arrays[left].key > key || arrays[right -1].key < key) //보간탐색 예외처리
return false;
//보간 탐색은 mid 를 구하지 않는다.
findIndex = left + (right - left) * (double)(key - arrays[left].key) / (arrays[right - 1].key - arrays[left].key);
if (arrays[findIndex].key == key)
{
index = findIndex;
return true;
}
else if (arrays[findIndex].key < key) //findIndex에 있는 값이 찾는값보다 작으면 오른쪽에서 찾는다.
left = findIndex + 1;
else if (arrays[findIndex].key > key) //findIndex에 있는 값이 찾는값보다 크면 왼쪽에서 찾는다.
right = findIndex - 1;
}
return false;
}
if (arrays[left].key > key || arrays[right -1].key < key) return false;
findIndex = left + (right - left) * (double)(key - arrays[left].key) / (arrays[right - 1].key - arrays[left].key);
이진 탐색에서 이 두 구간이 변경되었습니다.
감사합니다.
'IT > C C++' 카테고리의 다른 글
(C/C++) 검색 - AVL 트리 - 균형잡힌 트리 탐색 (Balanced Tree Search) (1) | 2021.06.01 |
---|---|
(C/C++) 검색 - 이진 트리 탐색 (Binary Tree Search) (1) | 2021.05.28 |
(C/C++) 검색 - 선형 탐색, 순차 탐색(Sequential Search) (1) | 2021.05.24 |
(C/C++) 정렬 - 퀵 정렬(Quick Sort) - 안정성 X, O(N log N) (1) | 2021.04.06 |
(C/C++) 정렬 - 병합 정렬(Merge Sort) - 안정성 O, O(N log N) (1) | 2021.04.05 |