트리 자료구조는 노드(점)과 그 사이의 간선으로 이루어져있다.
최상단의 노드는 루트 노드, 최하단의 노드는 리프노드, 그 사이 노드는 내부(Internal) 노드
트리의 높이는 최대 level + 1이며, 깊이(depth)라고도 한다.
노드의 차수란 그 노드의 자식(서브트리)의 수를 말한다.
이진트리는 재귀적으로 정의할 수 있다.
빈 트리이거나, 루트 노드+왼/오 서브 트리가 이진트리로 되어있는 트리
모든 레벨에서 노드들이 모두 채워져 있는 이진 트리
높이는 k이고, 노드의 개수가 2의 k승 - 1 개이다.
class Node:
def __init__(self, item):
self.data = item
self.left = None
self.right = None
class BinaryTree:
def __init__(self, r):
self.root = r
class BinaryTree:
def size(self):
if self.root:
return self.root.size()
else:
return 0
class Node:
def __init__(self, item):
self.data = item
self.left = None
self.right = None
def size(self):
l = self.left.size() if self.left else 0
r = self.right.size() if self.right else 0
return l + r + 1
def depth(self):
l = self.left.depth() if self.left else 0
r = self.right.depth() if self.right else 0
return max(l, r)+1
class BinaryTree:
def __init__(self, r):
self.root = r
def size(self):
if self.root:
return self.root.size()
else:
return 0
def depth(self):
if self.root:
return self.root.depth()
else:
return 0
def inorder(self):
traversal = []
if self.left:
traversal += self.left.inorder()
traversal.append(self.data)
if self.right:
traversal += self.right.inorder()
return traversal
def preorder(self):
traversal = []
traversal.append(self.data)
if self.left:
traversal += self.left.preorder()
if self.right:
traversal += self.right.preorder()
return traversal
def postorder(self):
traversal = []
if self.left:
traversal += self.left.postorder()
if self.right:
traversal += self.right.postorder()
traversal.append(self.data)
return traversal
수준(level)이 낮은 노드를 우선으로 방문,
같은 수준의 노드들 사이에서는 부모 노드의 방문 순서에 따라, 왼쪽부터 오른쪽으로 방문한다.
이 방식은 재귀적 방법으로 구현하지 못한다.
구현할 때 주의할 점
class BinaryTree:
def bft(self):
traversal = []
q = ArrayQueue()
if self.root:
q.enqueue(self.root)
while q.isEmpty() == False:
node = q.dequeue()
traversal.append(node.data)
if node.left:
q.enqueue(node.left)
if node.right:
q.enqueue(node.right)
return traversal
tree[root] = left, right
tree = {}
tree["A"] = "B", "C"
이렇게 tree의 인덱스는 KEY로, 저장되는 값은 VALUE로 사전에 저장할 수 있다.
{"A" : ("B","C")}
👉 의미 : A가 부모인 노드가 B, C / A의 자식이 B, C
※ A를 key로 가지는 value인 B를 인덱싱하는 방법 : tree["A"][0]
def height(root):
tree_h = 0
if root.left and root.right:
tree_lh = 1 + height(root.left)
tree_rh = 1 + height(root.right)
tree_h += max(tree_lh, tree_rh)
elif not root.left and root.right:
tree_rh = 1 + height(root.right)
tree_h += tree_rh
elif root.left and not root.right:
tree_lh = 1 + height(root.left)
tree_h += tree_lh
return tree_h
이진 트리의 노드 개수와 노드값들을 입력 받아 각각 전위 순회, 중위 순회, 후위 순회한 결과를 출력하는 문제
import sys
N = int(sys.stdin.readline().strip())
tree = {}
for n in range(N):
root, left, right = sys.stdin.readline().strip().split()
tree[root] = [left, right]
def preorder(root):
if root != '.':
print(root, end='') # root
preorder(tree[root][0]) # left
preorder(tree[root][1]) # right
def inorder(root):
if root != '.':
inorder(tree[root][0]) # left
print(root, end='') # root
inorder(tree[root][1]) # right
def postorder(root):
if root != '.':
postorder(tree[root][0]) # left
postorder(tree[root][1]) # right
print(root, end='') # root
preorder('A')
print()
inorder('A')
print()
postorder('A')
import sys
sys.setrecursionlimit(10**9) # 파이썬 재귀의 깊이 제한: 1000 -> 런타임 에러 발생
def dfs(v):
for i in graph[v]:
if not visited[i]:
visited[i] = v
dfs(i)
n = int(input())
graph = [[] for _ in range(n + 1)]
visited = [0] * (n + 1)
for _ in range(n - 1):
a, b = map(int, sys.stdin.readline().split())
graph[a].append(b)
graph[b].append(a)
dfs(1)
for i in range(2, n + 1):
print(visited[i])