Foundry
자료구조
기초
핵심

이진 탐색 트리 (BST)

왼쪽 < 루트 < 오른쪽 규칙의 이진 트리

이진 탐색 트리 (BST)

왼쪽 자식 < 부모 < 오른쪽 자식 규칙을 따르는 트리. 빠른 검색/삽입/삭제 가능.

구조

        8
       / \
      3   10
     / \    \
    1   6    14
       / \  /
      4   7 13

왼쪽 서브트리: 부모보다 작은 값 오른쪽 서브트리: 부모보다 큰 값

시간 복잡도

연산평균최악
검색O(log N)O(N)
삽입O(log N)O(N)
삭제O(log N)O(N)

최악의 경우

1 → 2 → 3 → 4 → 5
(정렬된 데이터 삽입 시)

    1
     \
      2
       \
        3  ← 사실상 연결리스트!
         \   O(N)
          4

→ 해결: 균형 트리 (AVL, Red-Black Tree)

삭제 3가지 경우

1) 리프 노드: 그냥 삭제
2) 자식 1개: 자식이 대체
3) 자식 2개:
   → 오른쪽 서브트리의 최솟값으로 대체
   (또는 왼쪽의 최댓값)

BST vs 배열 vs 해시

연산배열해시BST
검색O(N)O(1)O(log N)
정렬된 순회O(N log N)O(N log N)O(N)
최솟값/최댓값O(N)O(N)O(log N)
범위 검색O(N)O(N)O(log N+k)

정렬/범위 연산이 필요하면 BST가 유리

면접에서 이렇게 나옵니다

Q.BST의 정의와 특성을 설명해주세요.

모든 노드에 대해 왼쪽 하위 트리는 자기보다 작고 오른쪽은 크다는 규칙을 지키는 이진 트리입니다.

        8
      /   \
     3     10
    / \      \
   1   6      14

이 규칙에서 두 가지가 따라옵니다.

특성내용
탐색값을 비교해 한쪽을 버리며 내려간다. 평균 O(log n)
중위 순회왼쪽, 자기, 오른쪽 순으로 방문하면 정렬된 순서가 나온다

정렬된 순서를 얻을 수 있다는 점이 해시 테이블과의 결정적 차이입니다. 범위 조회("30에서 50 사이")와 이웃 값 찾기가 가능합니다.

흔한 실수: 규칙을 "왼쪽 자식 < 부모 < 오른쪽 자식"으로 좁게 말하는 것. 하위 트리 전체가 조건을 만족해야 합니다. 자식만 보면 통과하지만 손자에서 깨지는 트리는 BST가 아닙니다.

Q.이진 탐색 트리(BST)의 최악 시간복잡도는?

O(n) 입니다. 트리가 한쪽으로 기울어 사실상 연결 리스트가 되는 경우입니다.

1, 2, 3, 4, 5 를 순서대로 넣으면

1
 \
  2
   \
    3
     \
      4

탐색은 트리의 높이에 비례합니다. 균형이 잡히면 높이가 log n 이지만, 정렬된 데이터를 순서대로 넣으면 높이가 n 이 됩니다. 하필 실무에서 흔한 입력(시간순 id, 정렬된 목록)이 최악을 만듭니다.

흔한 실수: BST의 복잡도를 O(log n)이라고만 답하는 것. 평균이 O(log n)이고 최악이 O(n)입니다. 이 최악을 없애려고 AVL이나 레드블랙 트리처럼 회전으로 높이를 관리하는 구조를 씁니다.

Q.BST에서 노드 삭제 시 자식이 2개인 경우는?

지울 노드 자리에 중위 순회에서 바로 다음 값을 올립니다. 오른쪽 하위 트리의 가장 왼쪽 노드입니다.

        8  <- 지운다
      /   \
     3     10
          /  \
         9    14

오른쪽 하위 트리의 가장 왼쪽은 9
9 를 8 의 자리로 올리고, 원래 9 자리를 정리한다

이 값을 고르는 이유는 지운 값보다 크면서 가장 작은 값이라 BST 규칙이 그대로 유지되기 때문입니다. 왼쪽 하위 트리의 가장 오른쪽 값(지운 값보다 작으면서 가장 큰 값)을 써도 됩니다.

올릴 노드는 자식이 최대 하나이므로(가장 왼쪽이라 왼쪽 자식이 없다) 그 정리는 간단한 경우로 환원됩니다.

흔한 실수: 아무 자식이나 올리는 것. 오른쪽 자식을 그냥 올리면 그 하위 트리의 작은 값들이 규칙을 깨뜨립니다.

Q.균형 트리(AVL, Red-Black)가 왜 필요한가요?

높이가 곧 성능이고, 균형이 깨지면 높이가 n 까지 자라기 때문입니다. 균형 트리는 삽입과 삭제 때 회전으로 높이를 log n 안에 묶어둡니다.

구조균형 기준특징
AVL좌우 높이 차이가 1 이하더 엄격해 탐색이 빠르다. 회전이 잦다
레드블랙색 규칙으로 느슨하게 유지삽입과 삭제가 싸다. 표준 라이브러리가 많이 쓴다

읽기가 압도적으로 많으면 AVL, 쓰기가 섞이면 레드블랙이 유리합니다. Java의 TreeMap과 C++의 map 은 레드블랙 트리입니다.

흔한 실수: "균형 트리가 항상 빠르다"고 답하는 것. 회전 비용이 있어 삽입이 잦으면 오히려 느립니다. 그리고 데이터가 이미 무작위 순서로 들어온다면 일반 BST도 평균 log n 입니다.

Q.DB 인덱스에 B-tree를 쓰는 이유는?

디스크는 블록 단위로 읽기 때문에, 한 번 읽을 때 최대한 많은 키를 가져오는 구조가 유리합니다.

항목이진 트리B-tree
노드당 키1개수백 개 (한 블록에 담을 만큼)
100만 건의 높이약 203에서 4
디스크 읽기 횟수높이만큼높이만큼

디스크 접근이 메모리보다 수천 배 느리므로 읽기 횟수를 줄이는 것이 핵심입니다. 노드를 뚱뚱하게 만들어 높이를 낮추는 것이 B-tree 입니다.

리프가 서로 연결된 변형(B+tree)은 범위 조회에도 강합니다. 시작 지점을 찾은 뒤 리프를 따라 순차로 읽으면 됩니다.

흔한 실수: 해시 인덱스가 O(1)이라 더 좋다고 답하는 것. 해시는 등가 조회만 되고 범위 조회와 정렬을 못 합니다. DB 쿼리에는 범위와 ORDER BY 가 흔합니다.

Q.힙(Heap)과 BST의 차이를 설명해주세요

정렬의 강도가 다릅니다. BST는 전체 순서를, 힙은 부모와 자식 사이의 관계만 지킵니다.

항목BST
규칙왼쪽 < 부모 < 오른쪽부모가 자식보다 작다 (최소 힙)
형제 사이 순서정해진다정해지지 않는다
최솟값 찾기O(log n), 왼쪽 끝까지O(1), 뿌리가 최솟값
특정 값 찾기O(log n)O(n), 순서를 모른다
정렬 순회중위 순회로 가능불가능

그래서 가장 작은 것만 반복해서 꺼내는 우선순위 큐에는 힙을, 정렬된 순회와 범위 조회가 필요하면 BST를 씁니다.

흔한 실수: 힙에서 두 번째로 작은 값을 O(1)에 안다고 답하는 것. 두 자식 중 어느 쪽인지 비교해야 합니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

더 깊이 공부하기

읽었으면 문제로 확인해보세요

자료구조 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.