Skip to content

Commit e94099c

Browse files
authored
[Bona1122] 25.02.06 (#37)
* Tree traversal basic / 기초 * Complete binary tree / 기초 * Tree find parent / 기초 * Binary_tree_height / 기초 * Binary search tree / 중급 * Tree and query / 중급 * Tree_traversal / 심화
1 parent 80aaf9a commit e94099c

File tree

16 files changed

+489
-0
lines changed

16 files changed

+489
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// https://www.acmicpc.net/problem/5639
2+
// 이진 검색트리의 전위 순회 경과가 주어지면, 후위순회 결과 구하기
3+
const filePath =
4+
process.platform === "linux"
5+
? "/dev/stdin"
6+
: require("path").join(__dirname, "input.txt")
7+
const input = require("fs").readFileSync(filePath).toString().trim().split("\n")
8+
const log = console.log
9+
10+
const arr = input.map(Number)
11+
12+
const postorder = (root, end) => {
13+
if (root > end) return
14+
15+
let right = end + 1 // 오른쪽 서브트리(루트보다 큰 요소들) 시작점 구하기
16+
for (let i = root + 1; i <= end; i++) {
17+
if (arr[i] > arr[root]) {
18+
right = i
19+
break
20+
}
21+
}
22+
23+
// 후위 순위로 출력
24+
postorder(root + 1, right - 1)
25+
postorder(right, end)
26+
log(arr[root])
27+
}
28+
29+
postorder(0, arr.length - 1)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// https://www.acmicpc.net/problem/5639
2+
// 이진 검색트리의 전위 순회 경과가 주어지면, 후위순회 결과 구하기
3+
4+
// 핵심: BST의 전위순회 결과가 있기에, 순서대로 트리에 삽입하면 트리가 복원된다
5+
const filePath =
6+
process.platform === "linux"
7+
? "/dev/stdin"
8+
: require("path").join(__dirname, "input.txt")
9+
const input = require("fs").readFileSync(filePath).toString().trim().split("\n")
10+
const log = console.log
11+
12+
const arr = input.map(Number)
13+
14+
class Node {
15+
constructor(value) {
16+
this.value = value
17+
this.left = null
18+
this.right = null
19+
}
20+
}
21+
22+
class BinarySearchTree {
23+
constructor() {
24+
this.root = null
25+
}
26+
27+
insert(value) {
28+
if (!this.root) {
29+
this.root = new Node(value)
30+
return
31+
}
32+
33+
let current = this.root
34+
while (true) {
35+
if (value < current.value) {
36+
if (!current.left) {
37+
current.left = new Node(value)
38+
break
39+
}
40+
current = current.left
41+
} else {
42+
if (!current.right) {
43+
current.right = new Node(value)
44+
break
45+
}
46+
current = current.right
47+
}
48+
}
49+
}
50+
51+
postorder(node = this.root) {
52+
if (!node) return
53+
54+
this.postorder(node.left) // 왼쪽 서브트리 순회
55+
this.postorder(node.right) // 오른쪽 서브트리 순회
56+
log(node.value) // 현재 노드 출력
57+
}
58+
}
59+
60+
const tree = new BinarySearchTree()
61+
arr.forEach((item) => tree.insert(item))
62+
tree.postorder()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
50
2+
30
3+
24
4+
5
5+
28
6+
45
7+
98
8+
52
9+
60
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// https://www.acmicpc.net/problem/1068
2+
const filePath =
3+
process.platform === "linux"
4+
? "/dev/stdin"
5+
: require("path").join(__dirname, "input.txt")
6+
const input = require("fs").readFileSync(filePath).toString().trim().split("\n")
7+
const log = console.log
8+
9+
// 노드 제거시, 노드와 노드의 모든 자손이 트리에서 제거됨
10+
// 노드를 지운 후, 트리의 리프노드 개수 구하기
11+
// => 부모노드 정보를 통해 그래프를 구성하고, bfs로 탐색하며 리프노드 개수 카운트
12+
13+
const n = +input[0]
14+
const parents = input[1].split(" ").map(Number)
15+
const remove = +input[2]
16+
const graph = Array.from({ length: n }, () => [])
17+
let root = -1
18+
19+
for (let i = 0; i < n; i++) {
20+
const parent = parents[i]
21+
if (parent === -1) {
22+
root = i
23+
} else {
24+
graph[parent].push(i)
25+
}
26+
}
27+
28+
let result = 0
29+
const queue = remove === root ? [] : [root]
30+
const visited = new Array(n).fill(false)
31+
visited[root] = true
32+
33+
while (queue.length) {
34+
let item = queue.shift()
35+
let isLeaf = true
36+
37+
for (let v of graph[item]) {
38+
if (v !== remove) {
39+
isLeaf = false
40+
if (!visited[v]) {
41+
visited[v] = true
42+
queue.push(v)
43+
}
44+
}
45+
}
46+
47+
if (isLeaf) result++
48+
}
49+
50+
log(result)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
9
2+
-1 0 0 2 2 4 4 6 6
3+
4
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// https://www.acmicpc.net/problem/9934
2+
const filePath =
3+
process.platform === "linux"
4+
? "/dev/stdin"
5+
: require("path").join(__dirname, "input.txt")
6+
const input = require("fs").readFileSync(filePath).toString().trim().split("\n")
7+
const log = console.log
8+
9+
// 상근이는 중위순회로 이진 트리를 순회한 결과를 가지고 있다.
10+
// 각 레벨에 있는 빌딩 번호 구하기
11+
const k = +input[0]
12+
const arr = input[1].split(" ").map(Number)
13+
let result = Array.from({ length: k }, () => [])
14+
15+
const dfs = (arr, depth) => {
16+
if (arr.length < 1) return
17+
18+
const mid = Math.floor(arr.length / 2)
19+
result[depth].push(arr[mid])
20+
21+
dfs(arr.slice(0, mid), depth + 1)
22+
dfs(arr.slice(mid + 1), depth + 1)
23+
}
24+
25+
dfs(arr, 0)
26+
result.forEach((row) => log(row.join(" ")))
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
3
2+
1 6 4 3 5 2 7
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// https://www.acmicpc.net/problem/15681
2+
const filePath =
3+
process.platform === "linux"
4+
? "/dev/stdin"
5+
: require("path").join(__dirname, "input.txt")
6+
const input = require("fs").readFileSync(filePath).toString().trim().split("\n")
7+
const log = console.log
8+
9+
// 가중치, 방향 없는 트리
10+
// 정점 U를 루트로 하는 서브트리에 속한 정점 수 출력하기
11+
12+
// 방법 1: 문제에서 주어진 힌트 처럼, 자식 배열을 활용
13+
const [N, R, Q] = input[0].split(" ").map(Number)
14+
15+
const graph = Array.from({ length: N + 1 }, () => [])
16+
const query = Array(Q)
17+
const children = Array.from({ length: N + 1 }, () => [])
18+
const size = Array(N + 1).fill(1)
19+
20+
for (let i = 1; i <= N - 1; i++) {
21+
let [u, v] = input[i].split(" ").map(Number)
22+
graph[u].push(v)
23+
graph[v].push(u)
24+
}
25+
let idx = 0
26+
for (let i = N; i < N + Q; i++) {
27+
query[idx++] = +input[i]
28+
}
29+
30+
const makeTree = (cur, parent) => {
31+
for (let next of graph[cur]) {
32+
if (next !== parent) {
33+
children[cur].push(next)
34+
makeTree(next, cur)
35+
}
36+
}
37+
}
38+
39+
// 부모자식관계를 파악하기 위한 두 가지 방법
40+
// 1. 명시적으로 배열에 저장 -> makeTree 선행 필요
41+
const countSubtreeNodes = (cur) => {
42+
for (let next of children[cur]) {
43+
countSubtreeNodes(next)
44+
size[cur] += size[next]
45+
}
46+
}
47+
// 2. visited배열로 부모자식 파악
48+
const visited = Array(N + 1).fill(false)
49+
const countSubtreeNodes2 = (node) => {
50+
if (visited[node]) return size[node]
51+
visited[node] = true // 방문 표시로 부모-자식 관계 파악
52+
53+
for (const next of graph[node]) {
54+
if (!visited[next]) {
55+
// 방문하지 않은 노드는 자식
56+
size[node] += countSubtreeNodes2(next)
57+
}
58+
}
59+
return size[node]
60+
}
61+
/*
62+
makeTree(R, 0)
63+
countSubtreeNodes(R)
64+
log(children)
65+
*/
66+
countSubtreeNodes2(R)
67+
68+
for (let q of query) log(size[q])
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
9 5 3
2+
1 3
3+
4 3
4+
5 4
5+
5 6
6+
6 7
7+
2 3
8+
9 6
9+
6 8
10+
5
11+
4
12+
8
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// https://www.acmicpc.net/problem/11725
2+
3+
// 루트없는 트리 주어지면(트리루트 1), 2번노드부터 각 노드의 부모를 구하기
4+
// => 그래프 정보 저장하고, bfs로 탐색하면서 부모노드 찾기
5+
const filePath =
6+
process.platform === "linux"
7+
? "/dev/stdin"
8+
: require("path").join(__dirname, "input.txt")
9+
const input = require("fs").readFileSync(filePath).toString().trim().split("\n")
10+
const log = console.log
11+
12+
const n = +input[0]
13+
const graph = Array.from({ length: n + 1 }, () => [])
14+
for (let i = 1; i < n; i++) {
15+
let [v1, v2] = input[i].split(" ").map(Number)
16+
graph[v1].push(v2)
17+
graph[v2].push(v1)
18+
}
19+
20+
const visited = new Array(n + 1).fill(false)
21+
const parent = new Array(n + 1).fill(0)
22+
23+
const queue = [1]
24+
visited[1] = true
25+
26+
while (queue.length) {
27+
let item = queue.shift()
28+
29+
for (let v of graph[item]) {
30+
if (visited[v]) continue
31+
visited[v] = true
32+
queue.push(v)
33+
parent[v] = item
34+
}
35+
}
36+
log(result.slice(2).join("\n"))

0 commit comments

Comments
 (0)