Skip to content

Commit 6db685e

Browse files
authored
Merge pull request #15 from Gnu-Kenny/master
[4주차] DS_트리 & 그래프
2 parents f54ca14 + 1de39da commit 6db685e

File tree

12 files changed

+498
-0
lines changed

12 files changed

+498
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Min Heap
2+
3+
```
4+
1 5
5+
/ \ / \
6+
2 3 4 3
7+
/ \ / \
8+
4 5 1 2
9+
Min Heap Max Heap
10+
```
11+
12+
- Heap
13+
14+
- 최대 혹은 최소 값을 빠르게 찾기 위해 구현된 완전 이진트리를 기본으로한 자료구조
15+
16+
- Min Heap
17+
18+
- Root Node가 가장 작은 값이 되도록한 트리
19+
20+
- Max Heap
21+
22+
- 가장 큰 값이 맨 위에 오도록 자기 부모 노드에 자기 값보다 큰값을 두게 한 트리
23+
24+
## 최소 힙에 노드 삽입하기
25+
26+
1. 완전 트리에 맨끝에 노드를 추가
27+
28+
2. 자신의 부모 노드와 비교해 자기 값이 작을 경우 부모 노드와 값 변경
29+
30+
3. 2번 반복
31+
32+
### 시간 복잡도
33+
34+
- O(logn)
35+
36+
- 한 레벨에 절반씩 떨어짐
37+
38+
## 최소 힙에 노드 꺼내오기
39+
40+
1. 최소 힙에서 노드를 요청할땐 가장 작은 값인 루트를 꺼내온다.
41+
42+
2. 루트 자리에 가장 마지막 노드를 넣는다.
43+
44+
3. 자식 노드와 비교했을 때 더 작은 자식 노드의 값과 자리 교체
45+
46+
4. 3번 반복
47+
48+
### 시간 복잡도
49+
50+
- O(logn)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# DFS, BFS
2+
3+
## DFS
4+
5+
- Depth-First Search (DFS)
6+
7+
- inorder
8+
9+
- preorder
10+
11+
- postorder
12+
13+
- 마지막 노드와 만날때까지 Child Node 순회
14+
15+
- Stack으로 구현
16+
17+
### 구현 순서
18+
19+
1. 스택을 하나 만든다.
20+
21+
2. 처음에는 시작할 노드를 넣는다.
22+
23+
3. 스택에서 노드를 하나 꺼내서 해당 노드의 자식노드를 스택에 추가
24+
25+
4. 꺼낸 노드는 출력
26+
27+
5. 한번 스택에 담았던 노드는 다시 담지 않는다.
28+
29+
### DFS: Recursion
30+
31+
1. 시작 노드로 함수를 호출한다.
32+
33+
2. 함수를 호출하면 자식 노드를 호출하기 전에 자기 자신을 출력한다.
34+
35+
3.
36+
37+
## BFS
38+
39+
- Breath-First Search (BFS)
40+
41+
- Level 단위로 순회
42+
43+
- Queue로 구현
44+
45+
### 구현 순서
46+
47+
1. 큐를 하나 만든다.
48+
49+
2. 처음에는 시작할 노드를 넣는다.
50+
51+
3. 큐에서 노드를 하나 꺼내서 해당 노드의 자식노드를 큐에 추가
52+
53+
4. 꺼낸 노드는 출력
54+
55+
5. 한번 큐에 담았던 노드는 다시 담지 않는다.
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import java.util.Iterator;
2+
import java.util.LinkedList;
3+
import java.util.Stack;
4+
import java.util.NoSuchElementException;
5+
6+
class Queue<T> {
7+
8+
class Node<T> {
9+
private T data;
10+
private Node<T> next;
11+
12+
public Node(T data) {
13+
this.data = data;
14+
}
15+
}
16+
17+
private Node<T> first;
18+
private Node<T> last;
19+
20+
public void enqueue(T item) {
21+
Node<T> t = new Node<T>(item);
22+
23+
if (first == null) {
24+
first = last;
25+
}
26+
last = t;
27+
if (first == null) {
28+
first = last;
29+
}
30+
}
31+
32+
public T dequeue() {
33+
if (first == null) {
34+
throw new NoSuchElementException();
35+
}
36+
T data = first.data;
37+
38+
first = first.next;
39+
40+
if (first == null) {
41+
last = null;
42+
}
43+
return data;
44+
}
45+
46+
public T peek() {
47+
if (first == null) {
48+
throw new NoSuchElementException();
49+
}
50+
return first.data;
51+
}
52+
53+
public boolean isEmpty() {
54+
return first == null;
55+
}
56+
}
57+
58+
class Graph {
59+
class Node {
60+
int data;
61+
LinkedList<Node> adjacent;
62+
boolean marked;
63+
64+
Node(int data) {
65+
this.data = data;
66+
this.marked = false;
67+
adjacent = new LinkedList<Node>();
68+
}
69+
}
70+
71+
Node[] nodes;
72+
73+
Graph(int size) {
74+
nodes = new Node[size];
75+
for (int i = 0; i < size; i++) {
76+
nodes[i] = new Node(i);
77+
}
78+
}
79+
80+
// 노드의 관계를 저장
81+
void addEdge(int i1, int i2) {
82+
Node n1 = nodes[i1];
83+
Node n2 = nodes[i2];
84+
if (!n1.adjacent.contains(n2)) {
85+
n1.adjacent.add(n2);
86+
}
87+
if (!n2.adjacent.contains(n1)) {
88+
n2.adjacent.add(n1);
89+
}
90+
}
91+
92+
// bfs를 인자 없이 시작하면 0번부터 시작
93+
void dfs() {
94+
dfs(0);
95+
}
96+
97+
void dfs(int index) {
98+
Node root = nodes[index];
99+
Stack<Node> stack = new Stack<Node>();
100+
stack.push(root);
101+
root.marked = true;
102+
while (!stack.isEmpty()) {
103+
Node r = stack.pop();
104+
for (Node n : r.adjacent) {
105+
// 가져온 노드의 자식들 중 스택에 들어가지 않은 노드들만 스택에 추가
106+
if (n.marked == false) {
107+
n.marked = true;
108+
stack.push(n);
109+
}
110+
}
111+
visit(r);
112+
}
113+
}
114+
115+
void bfs() {
116+
bfs(0);
117+
}
118+
119+
void bfs(int index) {
120+
Node root = nodes[index];
121+
Queue<Node> queue = new Queue<Node>();
122+
queue.enqueue(root);
123+
root.marked = true;
124+
// 큐가 비어있을때까지 반복 작업
125+
while (!queue.isEmpty()) {
126+
Node r = queue.dequeue();
127+
// 큐에서 꺼낸 노드의 자식 노드들을 큐에 추가
128+
for (Node n : r.adjacent) {
129+
if (n.marked == false) {
130+
n.marked = true;
131+
queue.enqueue(n);
132+
}
133+
}
134+
// 가지고 나온 노드는 출력
135+
visit(r);
136+
}
137+
}
138+
139+
// 재귀 호출시 링크드리스트가 노드의 주소를 가지고 있기 때문에 재귀함수는 노드를 받는 형태가 되어야함.
140+
void dfsR(Node r) {
141+
if (r == null)
142+
return;
143+
r.marked = true;
144+
visit(r);
145+
for (Node n : r.adjacent) {
146+
if (n.marked == false) {
147+
dfsR(n);
148+
}
149+
}
150+
}
151+
152+
// 시작 노드를 다양하게 받기 위해 배열방의 인덱스를 인자로 받는 형태 구현
153+
void dfsR(int index) {
154+
Node r = nodes[index];
155+
dfsR(r);
156+
}
157+
158+
void dfsR() {
159+
dfsR(0);
160+
}
161+
162+
// 방문할때 출력하는 함수
163+
void visit(Node n) {
164+
System.out.print(n.data + " ");
165+
}
166+
}
167+
168+
/*
169+
* ------------------------------- 0 / 1 -- 3 7 | / | \ / | / | 5 2 -- 4 \ 6 - 8
170+
*/
171+
public class dfs_bfs {
172+
public static void main(String[] args) {
173+
Graph g = new Graph(9);
174+
g.addEdge(0, 1);
175+
g.addEdge(1, 2);
176+
g.addEdge(1, 3);
177+
g.addEdge(2, 4);
178+
g.addEdge(3, 4);
179+
g.addEdge(3, 5);
180+
g.addEdge(5, 6);
181+
g.addEdge(5, 7);
182+
g.addEdge(6, 8);
183+
g.dfsR();
184+
185+
}
186+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//Inorder (Left, Root, Right): 4 2 5 1 3
2+
//Preorder (Root, Left, Right): 1 2 4 5 3
3+
//Postorder (Left, Right, Root): 4 5 2 3 1
4+
5+
class Node {
6+
int data;
7+
Node left;
8+
Node right;
9+
}
10+
11+
class Tree {
12+
public Node root;
13+
14+
public void setRoot(Node node) {
15+
this.root = node;
16+
}
17+
18+
public Node getroot() {
19+
return root;
20+
}
21+
22+
public Node makeNode(Node left, int data, Node right) {
23+
Node node = new Node();
24+
node.data = data;
25+
node.left = left;
26+
node.right = right;
27+
return node;
28+
}
29+
30+
public void inorder(Node node) {
31+
if (node != null) {
32+
inorder(node.left);
33+
System.out.println(node.data);
34+
inorder(node.right);
35+
}
36+
}
37+
38+
public void preorder(Node node) {
39+
if (node != null) {
40+
System.out.println(node.data);
41+
preorder(node.left);
42+
preorder(node.right);
43+
}
44+
}
45+
46+
public void postorder(Node node) {
47+
if (node != null) {
48+
postorder(node.left);
49+
postorder(node.right);
50+
System.out.println(node.data);
51+
}
52+
}
53+
}
54+
55+
public class binary_tree {
56+
public static void main(String[] args) {
57+
Tree t = new Tree();
58+
Node n4 = t.makeNode(null, 4, null);
59+
Node n5 = t.makeNode(null, 5, null);
60+
Node n2 = t.makeNode(n4, 2, n5);
61+
Node n3 = t.makeNode(null, 3, null);
62+
Node n1 = t.makeNode(n2, 1, n3);
63+
t.setRoot(n1);
64+
t.inorder(t.getroot());
65+
66+
}
67+
}

0 commit comments

Comments
 (0)