~ 재미있는 중위순회 이야기 ~
class N {
constructor(val, left = null, right = null) {
this.val = val
this.left = left
this.right = right
}
}
/**
* @param {N} root
*
* 1
* / \
* 2 3
* / \
* 4 5
*
* 2 -> 1 -> 4 -> 3 -> 5
*
* tree가 이렇게 생겼다고 가정하자
*
* 중위순회는 왼쪽 -> 루트 -> 오른쪽 순으로 탐색하는 것을 의미한다.
* 위의 트리를 기준으로 중위 순회를 거쳐 나온 답은 [2, 1, 4, 3, 5]가 나오면 된다.
*
* 이렇게 만들기 위해서는 두 가지가 필요하다.
*
* 1. 분석의 대상인 Binary Tree
* 2. 값을 저장 할 stack
*
* tree와 stack은 궁합이 좋다.
*
* 과정을 수행 할 함수는 tree의 루트부터 탐색을 시작한다.
*
* currentNode를 stack에 push하고
* currentNode = currentNode.left로 currentNode를 계속 초기화 한다.
* tree의 왼쪽 자식의 끝까지 도달하면 자식 node들이 null이므로 왼쪽 자식을 찾아
* 내려가는 프로세스는 중단된다.
*
* 마지막 유효한 값이 있는 왼쪽 자식은 stack에 저장되어 있게 된다.
* 해당 stack을 pop하면서 값을 꺼내 result에 push한다.
* currentNode를 currentNode의 오른쪽 자식으로 초기화 한다.
*
* 위 트리를 예로 들면 2의 왼쪽 자식이 null이므로 stack에서 꺼낼 준비가 되었다.
* stack에서 2가 든 node를 꺼내어 값을 result에 밀어넣고 currentNode를 오른쪽 자식으로
* 초기화한다.
*
* 하지만 오른쪽 자식도 null이다.
*
* 오른쪽 자식도 null이므로 stack을 다시 pop해 루트를 꺼내온다.
* pop하면서 꺼내온 루트의 값을 result에 밀어넣고 currentNode를 오른쪽 자식으로 초기화한다.
* 오른쪽 자식으로 초기화하면서 루트의 오른쪽 자식의 하위 트리의 왼쪽 자식부터 위의 과정을 반복하게 된다.
*/
function inOrderTraversal(root) {
if(!root) return []
const stack = []
const result = []
let currentNode = root
while(stack.length || currentNode) {
if(currentNode) {
stack.push(currentNode)
currentNode = currentNode.left
} else {
currentNode = stack.pop()
result.push(currentNode.val)
currentNode = currentNode.right
}
}
return result
}
/*
1
/ \
2 3
/ \
4 5
*/
const tree = new N(1,
new N(2),
new N(3,
new N(4),
new N(5)
)
);
console.log(inOrderTraversal(tree))