


0🤔 리프는 트리의 가장 아래쪽 레벨에 있는 노드를 말하는 건가요?



| 방법 | 탐색 순서 |
|---|---|
| 전위 순회 | 노드 방문 -> 왼쪽 자식 -> 오른쪽 자식 |
| 중위 순회 | 왼쪽 자식 -> 노드 방문 -> 오른쪽 자식 |
| 후위 순회 | 왼쪽 자식 -> 오른쪽 자식 -> 노드 방문 |


탐색이라 썼는데 뭐 같은 말입니다.
🤔 이진 검색 트리에는 동일한 값이 여러 개 존재할 수 있나요?
key와 value를 함께 저장하면 됩니다.key의 순서 기준으로 배치하고, value로 중복 데이터를 관리하면 되겠죠.Node 클래스로 관리하겠습니다. 속성으로 왼쪽 자식 left, 오른쪽 자식 right, 값 key를 갖습니다.class Node:
def __init__(self, value):
self.left = None
self.right = None
self.value = value
SearchTree 클래스로 관리하겠습니다. 일단 루트 노드만 속성 root로 지정하겠습니다.class SearchTree:
def __init__(self):
self.root = None
찾는 값 < 노드 값인 경우, 왼쪽 자식 노드를 따라감찾는 값 > 노드 값인 경우, 오른쪽 자식 노드를 따라감
# class SearchTree 계속
# 노드 검색
def search(self, target):
curr = self.root # 루트노드 부터 시작
while curr:
if curr.value == target:
return True
elif target < curr.value:
curr = curr.left # 왼쪽을 따라감
elif curr.value < target:
curr = curr.right # 오른쪽을 따라감
return False # 탐색 실패

# class SearchTree 계속
def insert(self, target):
# 루트노드가 없을 때
if self.root is None:
self.root = Node(target)
else:
curr = self.root
while True:
# 왼쪽자식 추가
if target < curr.value:
if curr.left is None:
curr.left = Node(target)
break
curr = curr.left
# 오른쪽자식 추가
if curr.value < target:
if curr.right is None:
curr.right = Node(target)
break
curr = curr.right
# 동일 값 존재 시 추가 불가
if curr.value == target:
break
node.value를 출력# class SearchTree 계속
# 전위 순회: 루트 -> 현재 -> 오른쪽
def preorder(self, node):
if node:
print(node.value, end=' ')
self.preorder(node.left)
self.preorder(node.right)
# 중위 순회: 왼쪽 -> 현재 -> 오른쪽
def inorder(self, node):
if node:
self.inorder(node.left)
print(node.value, end=' ')
self.inorder(node.right)
# 후위 순회: 왼쪽 -> 오른쪽 -> 현재
def postorder(self, node):
if node:
self.postorder(node.left)
self.postorder(node.right)
print(node.value, end=' ')
삭제는 구현은 안 하겠습니다. 좀 많이 복잡해서 ㅠㅠ
리프 노드일 때
자식이 1개인 노드일 때

자식이 2개인 노드일 때

🤔 검색한 위치의 노드에 왼쪽, 오른쪽 자식이 모두 있으면 어떡하죠?
class Node:
def __init__(self, value):
self.left = None
self.right = None
self.value = value
class SearchTree:
def __init__(self):
self.root = None
# 노드 삽입
def insert(self, target):
# 루트노드가 없을 때
if self.root is None:
self.root = Node(target)
else:
curr = self.root
while True:
# 왼쪽자식 추가
if target < curr.value:
if curr.left is None:
curr.left = Node(target)
break
curr = curr.left
# 오른쪽자식 추가
if curr.value < target:
if curr.right is None:
curr.right = Node(target)
break
curr = curr.right
# 동일 값 존재 시 추가 불가
if curr.value == target:
break
# 노드 검색
def search(self, target):
curr = self.root
while curr:
if curr.value == target:
return True
elif target < curr.value:
curr = curr.left
elif curr.value < target:
curr = curr.right
return False
# class SearchTree 계속
# 전위 순회: 루트 -> 현재 -> 오른쪽
def preorder(self, node):
if node:
print(node.value, end=' ')
self.preorder(node.left)
self.preorder(node.right)
# 중위 순회: 왼쪽 -> 현재 -> 오른쪽
def inorder(self, node):
if node:
self.inorder(node.left)
print(node.value, end=' ')
self.inorder(node.right)
# 후위 순회: 왼쪽 -> 오른쪽 -> 현재
def postorder(self, node):
if node:
self.postorder(node.left)
self.postorder(node.right)
print(node.value, end=' ')

tree = SearchTree()
for num in [7, 3, 9, 1, 5, 8, 10]:
tree.insert(num)
print("전위 순회")
tree.preorder(tree.root) # 7 3 1 5 9 8 10
print("중위 순회")
tree.inorder(tree.root) # 1 3 5 7 8 9 10
print("후위 순회")
tree.postorder(tree.root) # 1 5 3 8 10 9 7
전위, 중위, 후위 순회
특정 값 탐색

삽입 및 삭제
🤔 트리가 균형잡혀 있는지 불균형한지는 어떻게 결정되나요?
3, 4, 5, 6, 7, 8, 9를 원소로 갖고 있습니다.6 -> 4 -> 8 -> 3 -> 5 -> 7 -> 9 순으로 입력되어, 균형되게 유지됐습니다.3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 순으로 삽입된 탓에, 오른쪽 자식으로만 노드가 추가돼서 불균형한 트리가 된 거죠.현재 노드, 값 -> `(왼쪽 자식, 오른쪽 자식)None 처리입력
# 입력이 다음과 같을 때
7 # 이진 트리 노드의 개수
# 순서대로 각 노드, 왼쪽 자식 노드, 오른족 자식 노드의 이름
# '.': 자식노드가 없다는 뜻
A B C
B D .
C E F
E . .
F . G
D . .
G . .
트리 만들기
for _ in range(N):
node, left, right = input().split()
tree[node] = (left, right)
print(tree)
# {'A': ('B', 'C'), 'B': ('D', '.'), 'C': ('E', 'F'), E': ('.', '.'), 'F': ('.', 'G'), 'D': ('.', '.'), G': ('.', '.')}
전위, 중위, 후위 순회
tree[node][0]을 매개변수로 재귀 호출tree[node][1]을 매개변수로 재귀 호출.인 경우 없는 노드 -> 종료 조건# 전위 순회
def preorder(node):
if node != ".":
print(node, end="")
preorder(tree[node][0])
preorder(tree[node][1])
# 중위 순회
def inorder(node):
if node != ".":
inorder(tree[node][0])
print(node, end="")
inorder(tree[node][1])
# 후위 순회
def postorder(node):
if node != ".":
postorder(tree[node][0])
postorder(tree[node][1])
print(node, end="")
# 루트 노드인 'A'부터 출발
preorder('A')
print()
inorder('A')
print()
postorder('A')
sys.setrecursionlimit(10 ** 9)로 설정import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**9)
class Node:
def __init__(self, x):
self.value = x
self.left = None
self.right = None
class Tree:
def __init__(self):
self.root = None
def insert(self, x):
if self.root is None:
self.root = Node(x)
curr = self.root
while curr is not None:
parent = curr
if x < curr.value:
is_left = True
curr = curr.left
elif x > curr.value:
is_left = False
curr = curr.right
elif x == curr.value:
return False
if is_left:
parent.left = Node(x)
else:
parent.right = Node(x)
tree = Tree()
while True:
try:
x = int(input())
tree.insert(x)
except:
break
def postorder(tree, node):
if node is not None:
postorder(tree, node.left)
postorder(tree, node.right)
print(node.value)
postorder(tree, tree.root)