아래는 내 코드.
전위순회(루트-왼쪽-오른쪽)를 받아서 일반적인 '이진 검색 트리'로 만들어주고, 그걸 다시 후위순회(왼쪽-오른쪽-루트)로 뽑아내는 코드이다.
import sys
tree = {}
sys.setrecursionlimit(10**4)
def postorder(tree, start):
if start == False or tree=={}:
return
postorder(tree, tree[start][0])
postorder(tree, tree[start][1])
print(start)
while True:
try:
num = int(sys.stdin.readline().strip())
if tree == {}:
tree[num] = [False, False] #left, right
root = num
else:
current = root
while True:
if num > current:
if tree[current][1] == False:
tree[current][1] = num
tree[num] = [False, False]
break
else:
current = tree[current][1]
else:
if tree[current][0] == False: #왼쪽 자식이 없다면
tree[current][0] = num
tree[num] = [False,False]
break
else:
current = tree[current][0]
except:
if tree=={}:
root = False
break
postorder(tree, root)
False대신 -1, 1을 대신 썼다가 틀렸습니다 늪에 빠졌었고
깊이가 10,000인 케이스에 대해선 런타임 에러 늪에 빠졌었다.(파이썬의 기본 탐색 깊이는 1,000으로 매우 얕다)
풀면서도 느낀 것이, 입력값이 전위순회이기 때문에 이를 잘 이용하면 굳이 이진 검색 트리로 저장한 후에 후위순회로 뱉지않고, 곧바로 후위순회로 뱉을 수 있지 않을까 생각은 했었다. (구현은 못했다...)
++ 더하여, 전위순회는 ( root - (왼 서브 트리: 새로운 root - (새로운 왼 서브 트리) - (새로운 오른 서브 트리))-(오른 서브 트리)) 로 나타나므로, 후위순회도 쉽게 프린트 될 거라 생각은 했는데, 구현하기 어려워서 내 풀이대로 코드를 짰었다.
솔루션을 보니, 내가 고민했던 바를 그대로 구현했더라. 갈 길이 멀다.
[솔루션]
import sys
sys.setrecursionlimit(10**4)
num_list=[]
while True:
try:
num = int(input())
num_list.append(num)
except:
break
def postorder(first, end):
if first > end:
return
mid = end + 1 # node보다 큰 값이 하나도 없을 때를 위한 처리
for i in range(first+1, end+1):
if num_list[first] < num_list[i]:
mid = i
break
postorder(first+1, mid-1)
postorder(mid, end)
print(num_list[first])
postorder(0, len(num_list)-1)