[Java] Tree
ํธ๋ฆฌ ์๋ฃ๊ตฌ์กฐ์ ์ข ๋ฅ : Tree, Binary Tree, Binary Serach Tree, Balanced Binary Serach Tree, Heap, Trie
์ด๋ฒ ํฌ์คํธ์์๋ ๊ธฐ๋ณธ์ ์ธ Tree์ ๋ํด์๋ง ์์ฑํด๋ณด์.
Tree๋ ?
Node์ Edge๋ก ๊ตฌ์ฑ๋ ๋ฐฉํฅ์ด ์กด์ฌํ๋ ๋น์ํ Graph์ ํ ์ข ๋ฅ์ด๋ค. ๊ทธ๋์ DAG(Directed Acyclic Graphs)๋ผ๊ณ ๋ ํ๋ค.
๊ทธ๋ผ Graph๋ก ๋ถ๋ฅํ๋ฉด ๋์ง ์ Tree๋๋ ์์ฌ์ ํ๊ฒ ๋๋ค.
Tree๋ Graph์์ ๋ช๊ฐ์ง ํน์ฑ์ ๋ ๊ฐ์ง๋ค.
1. ๋ฃจํธ ๋ ธ๋๊ฐ ํ๋ ์กด์ฌํ๋ค.
2. ๋ถ๋ชจ ๋ ธ๋๋ ํ๋๋ฐ์ ์กด์ฌํ์ง ์๋๋ค.
3. ๋ ธ๋๋ 0๊ฐ ์ด์์ ์์์ ๊ฐ์ง๊ณ ์๋ค.
4. ์์์ด 0๊ฐ์ธ ๊ฒฝ์ฐ ๋จ๋ง๋ ธ๋(Leaf Node)๋ผ๊ณ ํ๋ค.
5.. ์ ํน์ฑ์ ์งํค๋ ํธ๋ฆฌ์ ๊ฒฝ์ฐ ์ฃ์ง๊ฐ N-1๊ฐ์ด๋ค.
6. ์ฃ์ง๊ฐ N-1๊ฐ ์ด๋ฏ๋ก ๋ ์ ์ ๊ฐ ๊ฒฝ๋ก๋ 1๊ฐ์ง์ด๋ค.
package com.study.datastructrue.nonlinear.tree;
import java.util.ArrayList;
public class Node<T> {
private T data;
private ArrayList<Node> children;
public Node(final T data) {
this.data = data;
this.children = new ArrayList<>();
}
public T getData() {
return data;
}
public void setData(final T data) {
this.data = data;
}
public ArrayList<Node> getChildren() {
return children;
}
public void add(Node data) {
children.add(data);
}
}
๊ธฐ๋ณธ์ ์ธ ๋ ธ๋์ ์ ๋ณด์ด๋ค.
ํธ๋ฆฌ๋ DAG๋ผ๊ณ ํ์ผ๋ฏ๋ก ์์์ด ์ฌ๋ฌ๊ฐ ์ผ ์ ์๋ค.
package com.study.datastructrue.nonlinear.tree;
import java.util.ArrayList;
public class MyTree<T> {
private Node<T> root;
public MyTree() {
this.root = null;
}
public void add(T to, T data) {
if (this.root == null) {
this.root = new Node(data);
return ;
}
final Node node = findFirst(to);
if (node == null) {
throw new IllegalArgumentException("NOT Found Node");
}
node.add(new Node(data));
}
public Node findFirst(T data) {
if (root.getData() == data) return root;
return findFirst(root, data);
}
private Node findFirst(Node<T> cur, T data) {
for (int i = 0; i < cur.getChildren().size(); i++) {
if (cur.getChildren().get(i).getData() == data) {
return cur.getChildren().get(i);
}
}
for (Node node : root.getChildren()) {
return findFirst(node, data);
}
return null;
}
public void printTree() {
ArrayList<StringBuilder> sbs = new ArrayList<>();
final int depth = depth(root, 0);
for (int i = 0; i <= depth; i++) {
sbs.add(new StringBuilder());
}
printTree(root, 0, sbs);
for (StringBuilder sb: sbs) {
System.out.println(sb.toString());
}
}
private int depth(Node<T> cur, int level) {
int maxLevel = level;
for (int i = 0; i < cur.getChildren().size(); i++) {
maxLevel = Math.max(depth(cur.getChildren().get(i), level + 1), maxLevel);
}
return maxLevel;
}
private void printTree(Node<T> cur, int level, final ArrayList<StringBuilder> sbs) {
StringBuilder sb = sbs.get(level);
sb.append(cur.getData() + " ");
for (int i = 0; i < cur.getChildren().size(); i++) {
printTree(cur.getChildren().get(i), level + 1, sbs);
}
sb.append("|");
}
}
์๋ฌด๋ฐ ์ต์ ํ ์์ด ํธ๋ฆฌ๋ฅผ ์ค๊ณํ๊ฒ ๋๋ค๋ฉด ์ด๋ ๊ฒ ํจ์จ์ ์ด์ง ๋ชปํ๊ฒ ๋๋ค.
ํน์ ๋ ธ๋๋ฅผ ์ฐพ์ ๋์๋ ์์ ํ์์ ํด์ผํ๊ณ ํน์ ๋ ธ๋์ ์์์ผ๋ก ์ถ๊ฐํ๋ ค๊ฑฐ๋ ๊ต์ฒดํ๋ ค๋ฉด ํน์ ๋ ธ๋๋ฅผ ์ฐพ์์ผํ๋ฏ๋ก ๋ ๋ค์ ์์ ํ์์ ํ๊ฒ ๋๋ค.
์ด๋ฐ ๋นํจ์จ์ ์ธ ๋ฌธ์ ๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํด ์ด์ง ํ์ ํธ๋ฆฌ(Binary Search Tree)๋ผ๋ ๊ฒ์ด ๋์จ๋ค.
๊ธฐ์ค ๊ฐ๋ณด๋ค ์์ ๊ฐ์ ์ผ์ชฝ์ ํฐ ๊ฐ์ ์ค๋ฅธ์ชฝ์ ๋น์ ํ์ , ๊ณ์ธต์ ์ผ๋ก ์ ์ฅํด์ Log_2 N๋ฒ๋ง์ ๊ฒ์ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
๊ทธ๋ผ ์ผ์ง, ์ฌ์ง์ผ๋ก ๋๋๋ฉด ๋ ๋น ๋ฅด๊ฒ ๊ฒ์ํ ์ ์๋ ๊ฒ ์๋๊ฐ? ๋ผ๋ ์๊ฐ์ด ๋ค์๋๋ฐ ์ค์ ๋ก DB์์ ์ฌ์ฉํ๊ณ ์๋ค. ์ด ๋ถ๋ถ์ ๋์ค์ ์์ฑ.
package com.study.datastructrue.nonlinear.tree;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
public class Main {
public static void main(String[] args) {
// ๋ณต์กํ ํธ๋ฆฌ ์ค๊ณ
MyTree<Integer> tree = new MyTree<>();
tree.add(0, 1);
tree.add(1, 2);
tree.add(2, 3);
tree.add(2, 4);
tree.add(2, 5);
tree.printTree();
// PS์ฉ ๊ฐ๋จํ ADJ ํธ๋ฆฌ ์ค๊ณ
int vertexCount = 10;
int level[] = new int[vertexCount + 1];
ArrayList<ArrayList<Integer>> tree2 = new ArrayList<>();
ArrayList<StringBuilder> sbs = new ArrayList<>();
for (int i = 0; i <= vertexCount; i++) {
sbs.add(new StringBuilder());
tree2.add(new ArrayList<>());
}
tree2.get(1).add(2);
tree2.get(2).add(3);
tree2.get(2).add(4);
tree2.get(2).add(5);
Queue<Integer> q = new LinkedList<>();
q.add(1); level[1] = 1; sbs.get(1).append(1);
int maxLevel = 1;
// BFS
while (!q.isEmpty()) {
int x = q.poll();
maxLevel = Math.max(maxLevel, level[x]);
for (int i : tree2.get(x)) {
level[i] = level[x] + 1;
sbs.get(level[i]).append(i + " ");
q.add(i);
}
}
for (int i = 1; i <= maxLevel; i++) {
System.out.println(sbs.get(i).toString());
}
}
}
Graph์ ๊ฐ๊น์ด Tree ์ฌ์ฉ๊ณผ PS ์ฉ์ผ๋ก ์งง๊ฒ ์ฌ์ฉํ ์ ์๋ ์ฝ๋