한 개 이상의 노드로 이루어진 유한 집합이며 다음 조건을 만족한다
노드 중 최상위 노드를 루트라고 한다
나머지 노드들은 n개의 분리 집합 T1, ... TN으로 분리될 수 있다.
이들 T1, ... TN은 각각 하나의 트리가 되며(재귀적 정의) 루트의 부 트리(subtree)라고 한다.




트리의 각 노드를 중복되지 않게 전부 방문하는 것을 말하는데 트리는 비 선형 구조이기 때문에 선형 구조에서와 같이 선후 연결관계를 알 수 없다. 따라서 특별한 방법이 필요하다.
순회: 트리의 노드들을 체계적으로 방문하는 것
def preorder_traverse(T): #전위 순회
if T: #T is not None
visit(T) #print(T.item)
preorder_traverse(T_left)
preorder_traverse(T_right)


def inorder_traverse(T): #중위 순회
if T: #T is not None
inorder_traverse(T_left)
visit(T) #print(T.item)
inorder_traverse(T_right)

def postorder_traverse(T): #중위 순회
if T: #T is not None
postorder_traverse(T_left)
postorder_traverse(T_right)
visit(T) #print(T.item)


부모 번호를 인덱스로 자식 번호를 저장

자식 번호를 인덱스로 부모 번호를 저장

루트 찾기 / 조상 찾기

#첫 줄에는 트리의 정점의 총 수 V가 주어진다. 그 다음 줄에는 V-1개 간선이 나열된다.
#간선은 그것을 이루는 두 정점으로 표기된다. 간선은 항상 부모-자식 순서로 표기된다.
#간선은 부모 정점 번호가 작은 것부터 나열되고, 부모 정점이 동일하다면 자식 정점 번호가 작은 것부터 나열된다.
#아래 이진 트리 표현에 대해 전위 순회하여 정점의 번호를 출력하라.
'''
13
1 2 1 3 2 4 3 5 3 6 4 7 5 8 5 9 6 10 6 11 7 12 11 13
'''
#전위 순회
def pre_order(T):
if T:
print(T, end=' ')
pre_order(left[T])
pre_order(right[T])
N = int(input())
E = N-1
arr = list(map(int, input().split()))
left = [0]*(N+1) #부모를 인덱스로 왼쪽 자식번호 저장
right = [0]*(N+1) #부모를 인덱스로 오른쪽 자식번호 저장
par = [0]*(N+1) #자식을 인덱스로 부모 저장
for i in range(E):
p, c = arr[i*2], arr[i*2+1]
if left[p] == 0:
left[p] = c
else:
right[p] = c
par[c] = p
c = N
while par[c] != 0: #부모가 있으면
c = par[c] #부모를 새로운 자식으로 두고
root = c #더이상 부모가 없으면 root
pre_order(root)