Ch.6 트리 기초
BST — 정렬된 트리, 탐색/삽입
배열의 이진탐색을 트리에 담았다
이진 탐색 트리(BST)는 왼쪽 < 루트 < 오른쪽 규칙을 따르는 트리입니다. 이 단순한 규칙 하나가 O(log n) 탐색을 가능하게 합니다.
배열은 삽입이 느리고, 해시맵은 순서가 없다. BST는 둘 다 해결한다?
정렬 + 빠른 탐색 + 빠른 삽입 — BST가 왜 자료구조의 핵심인지 알아봅시다.
핵심 개념
BST(Binary Search Tree)
모든 노드에서 왼쪽 < 노드 < 오른쪽을 만족하는 이진 트리
BST 속성
중위 순회 시 오름차순으로 정렬된 결과를 얻는다
핵심 내용
이진 탐색 트리의 규칙은 딱 하나입니다
왼쪽 서브트리의 모든 값 < 루트 < 오른쪽 서브트리의 모든 값 이 규칙이 모든 서브트리에서 재귀적으로 성립합니다
BST 예시 8 / \ 3 10 / \ \ 1 6 14 / \ 4 7 중위 순회: [1, 3, 4, 6, 7, 8, 10, 14] ← 정렬!
찾고자 하는 값이 현재 노드보다 작으면 왼쪽, 크면 오른쪽으로 이동
def search_bst(root, target):
# Base case: 못 찾았거나 찾았거나
if not root:
return None
if target == root.val:
return root # 찾았다!
elif target < root.val:
return search_bst(root.left, target) # 왼쪽으로
else:
return search_bst(root.right, target) # 오른쪽으로
# 8에서 6을 찾는 과정:
# 8 → 6<8이니 왼쪽 → 3 → 6>3이니 오른쪽 → 6 찾았다!매 단계에서 탐색 범위가 절반으로 줄어듭니다. 이진탐색과 똑같은 원리! O(log n)
# 반복(iterative) 버전 — 면접에서 이걸 선호하는 경우도 있음
def search_bst_iter(root, target):
node = root
while node:
if target == node.val:
return node
elif target < node.val:
node = node.left
else:
node = node.right
return None # 못 찾음삽입도 탐색과 같은 경로를 따라갑니다. 빈 자리를 찾으면 거기에 넣으면 됩니다
def insert_bst(root, val):
# 빈 자리를 찾으면 새 노드 생성
if not root:
return TreeNode(val)
if val < root.val:
root.left = insert_bst(root.left, val)
elif val > root.val:
root.right = insert_bst(root.right, val)
# val == root.val 이면 중복 → 무시
return root
# BST에 5를 삽입:
# 8 → 5<8 왼쪽 → 3 → 5>3 오른쪽 → 6 → 5<6 왼쪽 → 빈 자리! 삽입삽입 후에도 BST 속성이 유지됩니다. 새 노드는 항상 리프 위치에 들어갑니다
BST의 성능은 트리의 모양에 달려 있습니다
균형 BST (Best/Average) • 탐색: O(log n) • 삽입: O(log n) • 삭제: O(log n) 편향 BST (Worst) • 탐색: O(n) • 삽입: O(n) • 삭제: O(n)
[1, 2, 3, 4, 5]를 순서대로 삽입하면? 오른쪽으로만 치우친 연결 리스트가 됩니다! 이것이 BST의 치명적 약점
# 편향 트리 예시 — 정렬된 데이터를 순서대로 삽입
# 1
# \
# 2
# \
# 3
# \
# 4
# \
# 5
# 높이 = n-1, 탐색 = O(n) ← 최악!이 문제를 해결하는 것이 다음 레슨의 주제 — 균형 트리(AVL)입니다
면접 단골 문제: 주어진 트리가 올바른 BST인지 검증하라
def isValidBST(root, lo=float('-inf'), hi=float('inf')):
if not root:
return True
# 현재 노드가 범위 밖이면 BST 아님
if root.val <= lo or root.val >= hi:
return False
# 왼쪽은 상한을 root.val로,
# 오른쪽은 하한을 root.val로 좁힘
return (isValidBST(root.left, lo, root.val) and
isValidBST(root.right, root.val, hi))함정 주의! 단순히 `left.val < node.val < right.val`만 확인하면 안 됩니다. 서브트리의 모든 값이 범위 안에 있어야 합니다
Validate BST — 핵심 아이디어 • 각 노드에 허용 범위 (lo, hi) 전달 • 왼쪽으로 가면 상한(hi) = 현재 값 • 오른쪽으로 가면 하한(lo) = 현재 값 • 시간: O(n), 공간: O(h)
BST에서 탐색의 평균 시간 복잡도는?
정렬된 배열 [1,2,3,4,5]를 순서대로 BST에 삽입하면 어떻게 되는가?
BST에 새로운 값을 삽입하면 항상 리프 위치에 들어간다
정리 노트
BST — 정렬된 트리
BST 핵심
- 규칙
- 왼쪽 < 루트 < 오른쪽 (모든 서브트리)
- 탐색/삽입
- 균형: O(log n), 편향: O(n)
- 중위 순회
- 오름차순 정렬 결과
면접 포인트
- Validate BST
- (lo, hi) 범위 전달 방식
- 편향 트리 문제
- → AVL/Red-Black으로 해결
시각 자료
퀴즈와 인터랙션으로 더 깊이 학습하세요
play_circle인터랙티브 레슨 시작