ํธ๋ฆฌ(Tree) ์๋ฃ๊ตฌ์กฐ์ ํ์
ํธ๋ฆฌ(Tree)
- ๋น์ ํ ์๋ฃ๊ตฌ์กฐ
- ์์๋ค ๊ฐ
1:n
์ ๊ด๊ณ๋ฅผ ๊ฐ์ง๋ ์๋ฃ๊ตฌ์กฐ - ์์๋ค ๊ฐ ๊ณ์ธต ๊ด๊ณ๋ฅผ ๊ฐ์ง๋ ๊ณ์ธตํ ์๋ฃ๊ตฌ์กฐ
- ์์ ์์์์ ํ์ ์์๋ก ๋ด๋ ค๊ฐ๋ฉฐ ํ์ฅ๋๋ ํธ๋ฆฌ(๋๋ฌด) ๋ชจ์์ ๊ตฌ์กฐ
- ํ์ฌ์ ์กฐ์ง๋, ํ์ผ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ, ๊ธฐ๊ณ ํ์ต์์์ ๊ฒฐ์ ํธ๋ฆฌ(decision tree) ๋ฑ์ ํํ
ํธ๋ฆฌ์ ๊ตฌ์ฑ ์์ ๋ฐ ์ฉ์ด ์ ๋ฆฌ
๊ตฌ์ฑ ์์
-
๋ ธ๋(Node) : ํธ๋ฆฌ์ ์์
- ๋ฃจํธ ๋ ธ๋(root node) : ํธ๋ฆฌ์ ์์ ๋ ธ๋์ธ ์ต์์ ๋ ธ๋
- ๋ฆฌํ ๋ ธ๋(leaf node) : ์ฐจ์๊ฐ 0์ธ ๋ ธ๋, ์์ ๋ ธ๋๊ฐ ์๋ ๋ ธ๋
- ํ์ ๋ ธ๋(sibling node) : ๊ฐ์ ๋ถ๋ชจ ๋ ธ๋๋ฅผ ๊ฐ๋ ์์ ๋ ธ๋๋ค
- ์กฐ์ ๋ ธ๋ : ๊ฐ์ ์ ๋ฐ๋ผ ๋ถ๋ชจ ๋ ธ๋๊น์ง ์ด๋ฅด๋ ๊ฒฝ๋ก์ ์๋ ๋ชจ๋ ๋ ธ๋๋ค
- ์์ ๋ ธ๋ : ์๋ธ ํธ๋ฆฌ์ ์๋ ํ์ ๋ ๋ฒจ์ ๋ ธ๋๋ค
- ๊ฐ์ (Edge) : ๋ ธ๋์ ๋ ธ๋๋ฅผ ์ฐ๊ฒฐํ๋ ์ ์ผ๋ก ํธ๋ฆฌ์์๋ ๋ถ๋ชจ ๋ ธ๋์ ์์ ๋ ธ๋๋ฅผ ์ฐ๊ฒฐ
- ์๋ธ ํธ๋ฆฌ(subtree) : ๋ถ๋ชจ ๋ ธ๋์ ์ฐ๊ฒฐ๋ ์ ์ ๋์์ ๋ ์์ฑ๋๋ ํธ๋ฆฌ
์ฉ์ด ์ ๋ฆฌ
-
์ฐจ์(degree)
- ๋ ธ๋์ ์ฐจ์ : ๋ ธ๋์ ์ฐ๊ฒฐ๋ ์์ ๋ ธ๋์ ์
- ํธ๋ฆฌ์ ์ฐจ์ : ๋ ธ๋์ ์ฐจ์ ์ค ์ต๋๊ฐ
-
๋์ด(level)
- ๋ ธ๋์ ๋์ด : ๋ฃจํธ๋ก๋ถํฐ ๋ ธ๋๊น์ง ์ด๋ฅด๋ ๊ฐ์ ์ ์
- ํธ๋ฆฌ์ ๋์ด : ๋ ธ๋์ ๋์ด ์ค ์ต๋๊ฐ
ํธ๋ฆฌ์ ๊ทธ๋ํ์ ์ฐจ์ด์
- ์ํ ๊ตฌ์กฐ(Cyclic) ๊ด๊ณ ์ฌ๋ถ : ํธ๋ฆฌ๋ ์ํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ์๋ ๊ทธ๋ํ.
- ๋ฐฉํฅ : ํธ๋ฆฌ๋ ๋ถ๋ชจ ๋ ธ๋์์ ์์ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋ ๋จ๋ฐฉํฅ๋ง ์กด์ฌํ๋ค.
- ๋ถ๋ชจ ๋ ธ๋์ ๋ฃจํธ ๋ ธ๋์ ๊ฐ์ : ํธ๋ฆฌ๋ ๋จ ํ๋์ ๋ถ๋ชจ ๋ ธ๋์ ๋ฃจํธ ๋ ธ๋๋ฅผ ๊ฐ์ง๋ค.
์ด์ง ํธ๋ฆฌ(Binary Tree)
- ์ฐจ์๊ฐ 2์ธ ํธ๋ฆฌ
- ๊ฐ ๋ ธ๋๊ฐ ์ต๋ 2๊ฐ์ ์์ ๋ ธ๋๋ฅผ ๊ฐ์ง ์ ์๋ ํธ๋ฆฌ(์ผ์ชฝ ์์ ๋ ธ๋, ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋)
- ๋ชจ๋ ๋ ธ๋๋ค์ด ์ต๋ 2๊ฐ์ ์๋ธ ํธ๋ฆฌ๋ฅผ ๊ฐ๋ ํน๋ณํ ํํ์ ํธ๋ฆฌ
์ด์ง ํธ๋ฆฌ์ ํน์ฑ
- ๊ณต์งํฉ๋ ์ด์งํธ๋ฆฌ
- ์๋ธ ํธ๋ฆฌ ๊ฐ ์์(์ผ์ชฝ, ์ค๋ฅธ์ชฝ)๊ฐ ์กด์ฌ
- ๋์ด i์์์ ๋
ธ๋์ ์ต๋ ๊ฐ์๋
2^i
๊ฐ - ๋์ด๊ฐ h์ธ ์ด์ง ํธ๋ฆฌ๊ฐ ๊ฐ์ง ์ ์๋ ์ต์ ๋
ธ๋ ๊ฐ์๋
h+1
๊ฐ, ์ต๋ ๋ ธ๋ ๊ฐ์๋2^(h+1) - 1
๊ฐ
์ด์ง ํธ๋ฆฌ์ ์ข ๋ฅ
ํฌํ ์ด์ง ํธ๋ฆฌ(Full Binary Tree)
- ๋ชจ๋ ๋์ด์ ๋ ธ๋๊ฐ ์ต๋๋ก ์ฐจ ์๋ ์ด์ง ํธ๋ฆฌ
- ๋ฐ๋ผ์ ๋
ธ๋ ๊ฐ์๋ ์ด์ง ํธ๋ฆฌ์ ์ต๋ ๋
ธ๋ ๊ฐ์์ธ
2^(h+1) - 1
๊ฐ - ๋ฃจํธ ๋ ธ๋๋ฅผ 1๋ฒ์ผ๋ก ํ์ฌ ๋ชจ๋ ๋ ธ๋๊ฐ ์์๋๋ก ๋ ธ๋ ๋ฒํธ๋ฅผ ๊ฐ์ง
์์ ์ด์ง ํธ๋ฆฌ(Complete Binary Tree)
- ๋ฃจํธ ๋ ธ๋๋ฅผ 1๋ฒ์ผ๋ก ํ์ฌ n๊ฐ์ ๋ ธ๋๋ฅผ ๊ฐ๋ ์ด์ง ํธ๋ฆฌ์์ 1๋ฒ๋ถํฐ n๋ฒ๊น์ง ๋น ์๋ฆฌ๊ฐ ์๋ ์ด์ง ํธ๋ฆฌ
- ๋ฎ์ ๋์ด์์ ์์ํ์ฌ ์ผ์ชฝ ์์ ๋ ธ๋๋ถํฐ ์ฑ์์ผ ํจ
ํธํฅ ์ด์ง ํธ๋ฆฌ(Skewed Binary Tree)
- ๋์ด h์ ๋ํ ์ต์ ๊ฐ์์ ๋ ธ๋๋ฅผ ๊ฐ์ง๋ฉฐ ํ ์ชฝ ๋ฐฉํฅ์ ์์ ๋ ธ๋๋ง์ ๊ฐ์ง ์ด์ง ํธ๋ฆฌ
- ๋ฐ๋ผ์ ๋
ธ๋ ๊ฐ์๋ ์ด์ง ํธ๋ฆฌ์ ์ต์ ๋
ธ๋ ๊ฐ์์ธ
h+1
๊ฐ
์ด์ง ํธ๋ฆฌ ํํ
๋ฐฐ์ด์ ์ด์ฉํ ์ด์ง ํธ๋ฆฌ ํํ
n๊ฐ์ ๋ ธ๋๋ฅผ ๊ฐ๋ ์ด์ง ํธ๋ฆฌ์ ๊ฒฝ์ฐ ๋ฃจํธ ๋ ธ๋๋ถํฐ ๋ง์ง๋ง ๋ ธ๋๊น์ง 1๋ฒ ~ n๋ฒ ๋ฒํธ๋ฅผ ๋งค๊ธด ๋ค, ๋ฐฐ์ด์ 1๋ฒ ์ธ๋ฑ์ค๋ถํฐ n๋ฒ ์ธ๋ฑ์ค๊น์ง ์์๋๋ก ๋ ธ๋๋ฅผ ์ฝ์ ํ์ฌ ๊ตฌํ
-
๋์ด๊ฐ h์ธ ์ด์ง ํธ๋ฆฌ๋ฅผ ๊ตฌํํ๊ธฐ ์ํด์๋ ๋ฐฐ์ด์ ํฌ๊ธฐ๊ฐ
2^(h+1)
๊ฐ ๋์ด์ผ ํจ.- ๋ฐฐ์ด์ 1๋ฒ ์ธ๋ฑ์ค๋ถํฐ ์ฌ์ฉํ๋ฏ๋ก ์ด์ง ํธ๋ฆฌ์ ์ต๋ ๋
ธ๋ ๊ฐ์์ธ
2^(h+1) - 1
๊ฐ๋ณด๋ค 1๊ฐ ๋ง์ ํฌ๊ธฐ
- ๋ฐฐ์ด์ 1๋ฒ ์ธ๋ฑ์ค๋ถํฐ ์ฌ์ฉํ๋ฏ๋ก ์ด์ง ํธ๋ฆฌ์ ์ต๋ ๋
ธ๋ ๊ฐ์์ธ
-
๋ฐฐ์ด์ ์ด์ฉํ ์ด์ง ํธ๋ฆฌ๋ ๊ตฌํ์ด ์ฝ์ง๋ง, ๋ฐฐ์ด ์์์ ๋ํ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ ๋ญ๋น๊ฐ ๋ฐ์ํ ์ ์์
- ํธํฅ ์ด์ง ํธ๋ฆฌ์ ๊ฒฝ์ฐ ์ฌ์ฉํ์ง ์๋ ๋ฐฐ์ด์ ์์ญ์ด ๋ง์์ง
- ํธ๋ฆฌ์ ์ค๊ฐ์ ์๋ก์ด ๋ ธ๋๋ฅผ ์ฝ์ ํ๊ฑฐ๋ ์ญ์ ํ ๊ฒฝ์ฐ ๋ฐฐ์ด์ ํฌ๊ธฐ ๋ณ๊ฒฝ์ด ์ด๋ ค์ ๋นํจ์จ์ ์
class CompleteBinaryTree {
private char[] nodes; // ํธ๋ฆฌ์ ๋
ธ๋
private final int SIZE; // ๋ฐฐ์ด์ ์ฌ์ด์ฆ ๊ณ ์
private int lastIndex; // ๋ง์ง๋ง์ ์ถ๊ฐ๋ ๋
ธ๋์ ์ธ๋ฑ์ค
public CompleteBinaryTree(int size) {
this.SIZE = size;
nodes = new char[SIZE+1]; // 1 ~ SIZE ๋ฒ์ ๋
ธ๋๋ค์ ์ ์ฅํ๋ ๋ฐฐ์ด
}
public void add(char c) {
if (lastIndex == SIZE) return; // ๋ฐฐ์ด ํฌํ ์ํ
nodes[++latIndex] = c; // ๋ฐฐ์ด์ ํธ๋ฆฌ ๋
ธ๋ ์ถ๊ฐ
}
}
๋งํฌ๋ฅผ ์ด์ฉํ ์ด์ง ํธ๋ฆฌ ํํ
์ด์ง ํธ๋ฆฌ ๋ ธ๋ ๋ฒํธ ์ฑ์ง์ ์ด์ฉํด ๊ฐ ๋ถ๋ชจ ๋ ธ๋์ ์ผ์ชฝ ์์ ๋ ธ๋์ ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋๋ฅผ ์ฐ๊ฒฐํ์ฌ ํํํ๋ค. ํ ๋ ธ๋๊ฐ ๋ ๊ฐ์ ๋งํฌ ํ๋๋ฅผ ๊ฐ๋ ํํ์ด๋ค.
๐ก ์ด์ง ํธ๋ฆฌ ๋ ธ๋ ๋ฒํธ์ ์ฑ์ง
- ๋ ธ๋ ๋ฒํธ๊ฐ i์ธ ๋ ธ๋์ ๋ถ๋ชจ ๋ ธ๋ ๋ฒํธ :
i/2
- ๋ ธ๋ ๋ฒํธ๊ฐ i์ธ ๋ ธ๋์ ์ผ์ชฝ ์์ ๋ ธ๋ ๋ฒํธ :
2*i
- ๋ ธ๋ ๋ฒํธ๊ฐ i์ธ ๋ ธ๋์ ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋ ๋ฒํธ :
2*i + 1
- ๋ ๋ฒจ n์ธ ๋ ธ๋์ ์์ ๋ฒํธ :
2^n
- ๋ฐฐ์ด ํํ๋ฒ์ ํ๊ณ์ธ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๋ฅผ ๋ง์ ์ ์๋ค. ์ด์ง ํธ๋ฆฌ์ ๋ ธ๋ ๊ฐ์๋งํผ ๋ ธ๋๋ฅผ ์์ฑํ๋ฉด ๋๋ค.
- ํน์ ๋ ธ๋๋ฅผ ํ์ํ๊ธฐ ์ํด ๋ฃจํธ ๋ ธ๋๋ถํฐ ํ์์ ์์ํด์ผ ํ๋ฏ๋ก ํ์์ด ๋นํจ์จ์ ์ด๋ค.
// ํธ๋ฆฌ์ ๋
ธ๋
class Node {
char data; // ๋ฐ์ดํฐ ํ๋
Node left; // ์ผ์ชฝ ์์ ๋
ธ๋ ๋งํฌ ํ๋
Node right; // ์ค๋ฅธ์ชฝ ์์ ๋
ธ๋ ๋งํฌ ํ๋
public Node(char data) {
this.data = data;
left = null; // ๋ฆฌํ ๋
ธ๋๋ฅผ ์ํ ์ด๊ธฐํ
right = null; // ๋ฆฌํ ๋
ธ๋๋ฅผ ์ํ ์ด๊ธฐํ
}
}
// ์์ ์ด์ง ํธ๋ฆฌ
class LinkedCompleteBinaryTree {
Node[] binaryTree;
public LinkedCompleteBinaryTree(int nodeCnt) {
binaryTree = new Node[nodeCnt+1]; // ๋
ธ๋ ๊ฐ์ + 1
}
public void add(int nodeCnt) {
for (int i=1; i<=nodeCnt; i++) {
binaryTree[i] = new Node(i); // ๋
ธ๋ ์์ฑ ๋ฐ ๋ฐ์ดํฐ ์ฝ์
}
for (int i=1; i<=nodeCnt/2; i++) {
binaryTree[i].left = binaryTree[2*i]; // ์ผ์ชฝ ์์ ๋
ธ๋ ์ฐ๊ฒฐ
binaryTree[i].right = binaryTree[2*i+1]; // ์ค๋์ชฝ ์์ ๋
ธ๋ ์ฐ๊ฒฐ
}
}
}
ํธ๋ฆฌ์ ํ์
๋น์ ํ ์๋ฃ๊ตฌ์กฐ์ธ ํธ๋ฆฌ์์ ๊ฐ ๋ ธ๋๋ฅผ ์ค๋ณต๋์ง ์๊ฒ ์์ ํ์ํ๊ธฐ ์ํ ๊ธฐ๋ฒ
๋๋น ์ฐ์ ํ์(BFS, Breadth First Search)
- ๋ฃจํธ ๋ ธ๋์ ์์ ๋ ธ๋๋ค์ ์ฐ์ ์ ์ผ๋ก ๋ชจ๋ ๋ฐฉ๋ฌธํ ๋ค, ๋ฐฉ๋ฌธํ๋ ์์ ๋ ธ๋๋ค์ ์์๋ ธ๋๋ค์ ๋ ๋ค์ ์ฐจ๋ก๋๋ก ๋ฐฉ๋ฌธํ๋ ๋ฐฉ์
- ์ธ์ ํ ๋ ธ๋์ ๋ํ ํ์์ด ๋๋์ผ ํด๋น ๋ ธ๋๋ค์ ์ธ์ ํ ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธํ ์ ์์ผ๋ฏ๋ก ์ ์ ์ ์ถ ํํ์ ์๋ฃ๊ตฌ์กฐ์ธ ํ(Queue)๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํํ ์ ์์
public void bfs() {
Queue<Integer> q = new LinkedList<>(); // ํ์์ ๊ธฐ๋ค๋ฆฌ๋ ๋
ธ๋ ์ ์ฅ
q.offer(1); // ๋ฃจํธ ๋
ธ๋์ ์ธ๋ฑ์ค
int level = 0, size = 0;
while(!q.isEmpty()) {
size = q.size(); // ํ์ฌ ๋์ด(๋๋น)์์์ ๋ชจ๋ ๋
ธ๋ ๊ฐ์
while(size-->0) { // ๋์ด ๋ณ ๋
ธ๋๋ค์ ๋จ๊ณ์ ์ผ๋ก ํ์ํ ์ ์์
int current = q.poll();
System.out.println(current + " ");
// ์ผ์ชฝ ์์ ๋
ธ๋ ์ ํจ์ฑ ๊ฒ์ฌ ํ ํ์ ์ฝ์
if (current*2 <= lastIndex) q.offer(current*2);
// ์ค๋ฅธ์ชฝ ์์ ๋
ธ๋ ์ ํจ์ฑ ๊ฒ์ฌ ํ ํ์ ์ฝ์
if (current*2+1 <= lastIndex) q.offer(current*2+1);
}
level++; // ํ์ฌ ๋์ด, ํ ๋์ด(๋๋น) ๋ณ ํ์์ด ๋๋๋ฉด ํฌ๊ธฐ ํ๋์ฉ ์ฆ๊ฐ
}
}
๊น์ด ์ฐ์ ํ์(DFS, Depth First Search)
- ๋ฃจํธ ๋ ธ๋์์ ์ถ๋ฐํ์ฌ ํ ๋ฐฉํฅ์ผ๋ก ๊ฐ ์ ์๋ ๊ฒฝ๋ก๊ฐ ์กด์ฌํ ๋๊น์ง ๊ณ์ํด์ ๊น์ด ํ์. ๋ ์ด์ ๋ฐฉ๋ฌธํ ์ ์๋ ๊ฒฝ๋ก๊ฐ ์์ผ๋ฉด ๋ง์ง๋ง์ผ๋ก ๋ง๋ฌ๋ ๊ฐ๋ฆผ๊ธธ์ด ์๋ ๋ ธ๋๋ก ๋์์ ๋ค๋ฅธ ๋ฐฉํฅ์ ๋ ธ๋๋ฅผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๊ณ์ํด์ ๊น๊ฒ ํ์ํ๋ ๋ฐฉ์
- ์์์ ์์์ ์์ ๋ ธ๋๊น์ง ๊น๊ฒ ํ์ํ๋ค๊ฐ ๋ฐฉ๋ฌธํ ๋ ธ๋๊ฐ ์์ ๊ฒฝ์ฐ ๋์์์ ๋ค๋ฅธ ์์ ๋ ธ๋๋ก ๊น๊ฒ ๋ค์ด๊ฐ์ผ ํ๋ฏ๋ก ์ฌ๊ท์ ์ผ๋ก ๊ตฌํํ๊ฑฐ๋, ํ์ ์ ์ถ ํํ์ ์๋ฃ๊ตฌ์กฐ์ธ ์คํ(Stack)์ ์ฌ์ฉํ์ฌ ๊ตฌํํ ์ ์์
public void dfs(int current) {
System.out.println(current + " "); // ์ ์ ์ํ dfs๋ก, ์ค์, ํ์ ์์์ ๊ฒฝ์ฐ ํ์ฌ ๋ผ์ธ์ ์์น๋ง ์์ ๋
ธ๋ ์ค๊ฐ๊ณผ ๋ง์ง๋ง์ผ๋ก ๋ฐ๊ฟ์ฃผ๋ฉด ๋จ
// ์ผ์ชฝ ์์ ๋
ธ๋ ์ ํจ์ฑ ๊ฒ์ฌ ํ ์ฌ๊ท์ ํ์
if (current*2 <= lastIndex) dfs(current*2);
// ์ค๋ฅธ์ชฝ ์์ ๋
ธ๋ ์ ํจ์ฑ ๊ฒ์ฌ ํ ์ฌ๊ท์ ํ์
if (current*2+1 <= lastIndex) dfs(current*2+1);
}
ํธ๋ฆฌ์ ์ํ
๊น์ด ์ฐ์ ํ์ ์ ํธ๋ฆฌ์ ๋ ธ๋๋ฅผ ์ํํ๋ ์์
์ ์ ์ํ(preorder traversal) : VLR
๋ ธ๋ ๋ฐฉ๋ฌธ -> ์ผ์ชฝ ์์ -> ์ค๋ฅธ์ชฝ ์์
public void dfsByPreOrder() {
System.out.print("Preorder : ");
dfsByPreOrder(1);
System.out.println();
}
private void dfsByPreOrder(int current) {
// ํ์ฌ ๋
ธ๋ ์ฒ๋ฆฌ
System.out.print(nodes[current] + " ");
// ์ผ์ชฝ ์์ ๋
ธ๋ ๋ฐฉ๋ฌธ
if (current*2<=lastIndex) dfsByPreOrder(current*2);
// ์ค๋ฅธ์ชฝ ์์ ๋
ธ๋ ๋ฐฉ๋ฌธ
if (current*2+1<=lastIndex) dfsByPreOrder(current*2+1);
}
์ค์ ์ํ(inorder traversal) : LVR
์ผ์ชฝ ์์ -> ๋ ธ๋ ๋ฐฉ๋ฌธ -> ์ค๋ฅธ์ชฝ ์์
public void dfsByInOrder() {
System.out.print("Inorder : ");
dfsByInOrder(1);
System.out.println();
}
private void dfsByInOrder(int current) {
// ์ผ์ชฝ ์์ ๋
ธ๋ ๋ฐฉ๋ฌธ
if (current*2<=lastIndex) dfsByInOrder(current*2);
// ํ์ฌ ๋
ธ๋ ์ฒ๋ฆฌ
System.out.print(nodes[current] + " ");
// ์ค๋ฅธ์ชฝ ์์ ๋
ธ๋ ๋ฐฉ๋ฌธ
if (current*2+1<=lastIndex) dfsByInOrder(current*2+1);
}
ํ์ ์ํ(postorder traversal) :LRV
์ผ์ชฝ ์์ -> ์ค๋ฅธ์ชฝ ์์ -> ๋ ธ๋ ๋ฐฉ๋ฌธ
public void dfsByPostOrder() {
System.out.print("Postorder : ");
dfsByPostOrder(1);
System.out.println();
}
private void dfsByPostOrder(int current) {
// ์ผ์ชฝ ์์ ๋
ธ๋ ๋ฐฉ๋ฌธ
if (current*2<=lastIndex) dfsByPostOrder(current*2);
// ์ค๋ฅธ์ชฝ ์์ ๋
ธ๋ ๋ฐฉ๋ฌธ
if (current*2+1<=lastIndex) dfsByPostOrder(current*2+1);
// ํ์ฌ ๋
ธ๋ ์ฒ๋ฆฌ
System.out.print(nodes[current] + " ");
}