"가장 단순한 탐색은 찾을 때까지 전부 들여다보는 거야. 하나도 영리하지 않은데, 그게 정확히 핵심이야. 영리하지 않은 O(n) 훑기가 진짜 정답일 때가 있고, 그걸 굳이 과잉 설계하는 쪽이 실수거든."
숨길 게 없는 알고리즘
선형 탐색은 컬렉션을 원소 하나씩 걸으면서 찾는 값이 나오거나 끝에 닿으면 멈춰. 길이가 n인 시퀀스에서 최악은 O(n)이고, 첫 원소가 바로 그 값이면 최선은 O(1)이야. 별도 인덱스가 없는, 정렬되지 않은 임의의 시퀀스에는 자연스러운 기본값이지. 다만 값의 범위나 저장 구조에 대한 추가 정보가 있다면 해시 인덱스나 직접 주소법 같은 다른 선택지도 열려.
과잉 설계 함정
여기서 진짜로 다루는 건 판단이야. 이진 탐색과 해시맵을 배우고 나면 반사적으로 그쪽으로 손이 가거든. 그런데 생각해 봐. 정렬 안 된 데이터를 이진 탐색하려면 먼저 정렬해야 하고, 그게 O(n log n)이야. 한 번 훑는 O(n)보다 더 비싸지. 정렬 안 된 데이터를 한 번 찾을 거라면 선형 탐색이 완승이야. 화려한 구조는 준비 비용이 여러 번의 탐색에 걸쳐 분할 상환될 때라야 본전을 뽑아. 한 번만 조회할 데이터에 이진 탐색을 꺼내는 건 전형적인 조기 최적화고. n 한 번을 아끼려고 n log n을 치른 셈이니까.
Python다운 형태들
반복문을 손으로 쓸 일은 드물어. Python이 선형 탐색을 표현력 있는 형태로 여러 개 주거든. x in items는 있는지 묻고, items.index(x)는 어디 있는지 묻고, any(pred(x) for x in items)는 조건에 맞는 게 하나라도 있는지 묻고, next((x for x in items if pred(x)), default)는 첫 번째로 맞는 걸, 없으면 기본값을 줘. 전부 속으로는 O(n) 훑기야. 이게 선형이라는 걸 알아야 반복문 안에 무심코 넣어서 O(n²)를 만드는 사고를 막을 수 있어. 복잡도 트랙에서 본 그 함정 말이야.