[이코테]순차탐색과 이진탐색

순차 탐색

순차 탐색(Sequential Search)이란 리스트 안에 있는 특정한 데이터를 찾기 위해 앞에서부터 데이터를 하나씩 차례대로 확인하는 방법이다. 

보통 정렬되지 않은 리스트에서 데이터를 찾아야 할 때 사용한다. 리스트 내에 데이터가 아무리 많아도 시간만 충분하다면 항상 원하는 원소를 찾을 수 있다는 장점이 있다.

 

#순차 탐색 코드

def sequentail_search(n,target,array):
  #각 원소를 하나씩 확인하며
  for i in range(n):
    #현재의 원소가 찾고자 하는 원소가 동일한 경우
    if array[i] == target:
      return i+1 #현재의 위치 변환(인덱스는 0부터 시작하므로 1더하기)
  
print('생성할 원소 개수를 입력한 다음 한 칸 띄고 찾을 문자열을 입력하세요.')
input_data = input().split()
n = int(input_data[0]) #원소의 개수
target = input_data[1] #찾고자 하는 문자열

print('앞서 적은 원소 개수만큼 문자열을 입력하세요. 구분은 띄어쓰기 한 칸으로 합니다.')
array = input().split()

#순차 탐색 수형결과 출력
print(sequentail_search(n,target,array))

순차 탐색은 데이터 정렬 여부와 상관없이 가장 앞에 있는 원소부터 하나씩 확인해야 한다는 점이 특징이다. 따라서 데이터의 개수가 N개일 때 최대 N번의 비교 연산이 필요하므로 최악의 경우 시작 복잡도는 O(N)이다.


이진 탐색

이진 탐색 (Binary Search)은 배열 내부의 데이터가 정렬되어 있어야만 사용할 수 있는 알고리즘이다. 데이터가 무작위일 때는 사용할 수 없지만, 이미 정렬되어 있다면 매우 빠르게 데이터를 찾을 수 있다는 특징이 있다. 이진 탐색은 탐색 범위를 절반씩 좁혀가며 데이터를 탐색하는 특징이 있다.

#이진탐색 :반으로 쪼개면서 탐색하기
#이진탐색 구현 (재귀 함수)
def binary_search(array,target,start,end):
  if start > end:
    return None
  mid = (start + end) // 2
  #찾은 경우 중간점 인덱스 반환
  if array[mid] == target:
    return mid
  #중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인
  elif array[mid] > target:
    return binary_search(array,target,start,mid-1)
  #중간점의 값보다 찾고자 하는 값이 오른쪽인 경우 오른쪽 확인
  else:
    return binary_search(array,target,mid+1,end)

#n(원소의 개수)가 target(찾고자 하는 문자열)을 입력받기
n,target = list(map(int,input().split()))
#전체 원소 입력받기
array = list(map(int,input().split()))

  #이진 탐색 수행 결과 출력
result = binary_search(array,target,0,n-1)
if result == None:
  print('원소가 존재하지 않습니다')
else:
  print(result +1)

 

재귀 함수로 구현한 이진 탐색

 

반복문으로 구현한 이진 탐색
def binary_search(array,target,start,end):
  while start <= end:
    mid = (start+end) //2
    #찾은 경우 중간점 인덱스 반환
    if array[mid] == target:
      return mid
    #중간점 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인
    if array[mid] > target:
      end = mid - 1
    #중간점 값보다 찾고자 하는 값이 큰 경우 오른쪽 확인
    else:
      start = mid + 1
  return None

#n(원소의 개수)가 target(찾고자 하는 문자열) 입력받기
n,target = list(map(int,input().split()))
#전체 원소 입력받기
array = list(map(int,input().split()))
#이진 탐색 수형 결고 출력
result = binary_search(array,target,0,n-1)
if result == None:
  print('원소가 존재하지 않습니다.')
else:
  print(result + 1)

반복문으로 구현한 이진 탐색

 

이진 탐색은 한 번 확인할 때마다 확인하는 원소의 개수가 절반씩 줄어든다는 점에서 시간 복잡도가 O(logN)이다. 절반씩 데이터를 줄어들도록 만든다는 점은 퀵 정렬과 공통점이 있다.


코딩 테스트에서 이용할 경우가 많은 이진 탐색이다. 탐색 범위가 2.000만을 넘어가면 이진 탐색을 활용해서 풀어보도록 하자.

'Algorithm' 카테고리의 다른 글

[BOJ/백준] 10816 숫자 카드 2  (0) 2020.11.19
[BOJ/백준]1920번 수 찾기  (0) 2020.11.17
[백준/BOJ] 2108번 통계학  (0) 2020.11.16
[이코테]계수정렬  (0) 2020.11.16
[이코테]정렬알고리즘의 개요  (0) 2020.11.15
<