Skip to content

Commit 82429ff

Browse files
committed
[Gold IV] Title: 트리 순회, Time: 92 ms, Memory: 98800 KB -BaekjoonHub
1 parent 2f6fd6d commit 82429ff

2 files changed

Lines changed: 126 additions & 0 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# [Gold IV] 트리 순회 - 22856
2+
3+
[문제 링크](https://www.acmicpc.net/problem/22856)
4+
5+
### 성능 요약
6+
7+
메모리: 98800 KB, 시간: 92 ms
8+
9+
### 분류
10+
11+
그래프 이론, 그래프 탐색, 트리
12+
13+
### 제출 일자
14+
15+
2025년 5월 30일 20:31:08
16+
17+
### 문제 설명
18+
19+
<p>노드가 <mjx-container class="MathJax" jax="CHTML" style="font-size: 109%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mi class="mjx-i"><mjx-c class="mjx-c1D441 TEX-I"></mjx-c></mjx-mi></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>N</mi></math></mjx-assistive-mml><span aria-hidden="true" class="no-mathjax mjx-copytext">$N$</span></mjx-container>개인 이진 트리가 있다. 트리를 중위 순회와 유사하게 순회하려고 한다. 이를 <strong>유사 중위 순회</strong>라고 하자.</p>
20+
21+
<p>순회의 시작은 트리의 루트이고 순회의 끝은 중위 순회할 때 마지막 노드이다. 이때 루트 노드는 항상 1번 노드이다.</p>
22+
23+
<p>유사 중위 순회는 루트 노드에서 시작하며, 다음과 같이 진행된다.</p>
24+
25+
<ol>
26+
<li>현재 위치한 노드의 왼쪽 자식 노드가 존재하고 아직 방문하지 않았다면, 왼쪽 자식 노드로 이동한다.</li>
27+
<li>그렇지 않고 현재 위치한 노드의 오른쪽 자식 노드가 존재하고 아직 방문하지 않았다면, 오른쪽 자식 노드로 이동한다.</li>
28+
<li>그렇지 않고 현재 노드가 유사 중위 순회의 끝이라면, 유사 중위 순회를 종료한다.</li>
29+
<li>그렇지 않고 부모 노드가 존재한다면, 부모 노드로 이동한다.</li>
30+
<li>유사 중위 순회를 종료할 때까지 1 ~ 4를 반복한다.</li>
31+
</ol>
32+
33+
<p style="text-align: center;"><img alt="" src="https://upload.acmicpc.net/ee01f435-9a8b-4d85-9720-4355f541fd4d/-/preview/" style="height: 392px; width: 600px;"></p>
34+
35+
<p>위 그림에 있는 트리에서 중위 순회를 한다면 <mjx-container class="MathJax" jax="CHTML" style="font-size: 109%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mn class="mjx-n"><mjx-c class="mjx-c34"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c32"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c35"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c31"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c36"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c33"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c37"></mjx-c></mjx-mn></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>4</mn><mo stretchy="false">→</mo><mn>2</mn><mo stretchy="false">→</mo><mn>5</mn><mo stretchy="false">→</mo><mn>1</mn><mo stretchy="false">→</mo><mn>6</mn><mo stretchy="false">→</mo><mn>3</mn><mo stretchy="false">→</mo><mn>7</mn></math></mjx-assistive-mml><span aria-hidden="true" class="no-mathjax mjx-copytext">$4 \rightarrow 2 \rightarrow 5 \rightarrow 1 \rightarrow 6 \rightarrow 3 \rightarrow 7$</span></mjx-container> 순으로 순회를 한다.</p>
36+
37+
<p>따라서, <strong>유사 중위 순회의 끝</strong>은 노드 7이 된다.</p>
38+
39+
<p style="text-align: center;"><img alt="" src="https://upload.acmicpc.net/c6cd786c-4235-499f-8ef2-57cdafd33ce7/-/crop/2544x1786/0,0/-/preview/" style="height: 421px; width: 600px;"></p>
40+
41+
<p><strong>유사 중위 순회</strong>는 위 그림과 같이 루트인 노드 <mjx-container class="MathJax" jax="CHTML" style="font-size: 109%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mn class="mjx-n"><mjx-c class="mjx-c31"></mjx-c></mjx-mn></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>1</mn></math></mjx-assistive-mml><span aria-hidden="true" class="no-mathjax mjx-copytext">$1$</span></mjx-container>에서 시작하여 노드 <mjx-container class="MathJax" jax="CHTML" style="font-size: 109%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mn class="mjx-n"><mjx-c class="mjx-c37"></mjx-c></mjx-mn></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>7</mn></math></mjx-assistive-mml><span aria-hidden="true" class="no-mathjax mjx-copytext">$7$</span></mjx-container>에서 끝나고 <mjx-container class="MathJax" jax="CHTML" style="font-size: 109%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mn class="mjx-n"><mjx-c class="mjx-c31"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c32"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c34"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c32"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c35"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c32"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c31"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c33"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c36"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c33"></mjx-c></mjx-mn><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2192"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c37"></mjx-c></mjx-mn></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>1</mn><mo stretchy="false">→</mo><mn>2</mn><mo stretchy="false">→</mo><mn>4</mn><mo stretchy="false">→</mo><mn>2</mn><mo stretchy="false">→</mo><mn>5</mn><mo stretchy="false">→</mo><mn>2</mn><mo stretchy="false">→</mo><mn>1</mn><mo stretchy="false">→</mo><mn>3</mn><mo stretchy="false">→</mo><mn>6</mn><mo stretchy="false">→</mo><mn>3</mn><mo stretchy="false">→</mo><mn>7</mn></math></mjx-assistive-mml><span aria-hidden="true" class="no-mathjax mjx-copytext">$1 \rightarrow 2 \rightarrow 4 \rightarrow 2 \rightarrow 5 \rightarrow 2 \rightarrow 1 \rightarrow 3 \rightarrow 6 \rightarrow 3 \rightarrow 7$</span></mjx-container> 이와 같은 순서로 순회를 진행한다. <strong>유사 중위 순회</strong>를 진행하면서 총 10번 이동하였다.</p>
42+
43+
<p>여기서 이동이라는 것은 하나의 노드에서 다른 노드로 한번 움직이는 것을 의미한다. 예를 들면, 노드 1에서 노드 2로 가는 것을 한번 이동하였다고 한다.</p>
44+
45+
<p><strong>유사 중위 순회</strong>를 하면서 이동한 횟수를 구하려고 한다.</p>
46+
47+
### 입력
48+
49+
<p>첫 번째 줄에 트리를 구성하는 노드의 개수 <mjx-container class="MathJax" jax="CHTML" style="font-size: 109%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mi class="mjx-i"><mjx-c class="mjx-c1D441 TEX-I"></mjx-c></mjx-mi></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>N</mi></math></mjx-assistive-mml><span aria-hidden="true" class="no-mathjax mjx-copytext">$N$</span></mjx-container>이 주어진다.</p>
50+
51+
<p>두 번째 줄부터 <mjx-container class="MathJax" jax="CHTML" style="font-size: 109%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mi class="mjx-i"><mjx-c class="mjx-c1D441 TEX-I"></mjx-c></mjx-mi><mjx-mo class="mjx-n" space="3"><mjx-c class="mjx-c2B"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="3"><mjx-c class="mjx-c31"></mjx-c></mjx-mn></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>N</mi><mo>+</mo><mn>1</mn></math></mjx-assistive-mml><span aria-hidden="true" class="no-mathjax mjx-copytext">$N + 1$</span></mjx-container> 번째 줄까지 현재 노드 <mjx-container class="MathJax" jax="CHTML" style="font-size: 109%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mi class="mjx-i"><mjx-c class="mjx-c1D44E TEX-I"></mjx-c></mjx-mi></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>a</mi></math></mjx-assistive-mml><span aria-hidden="true" class="no-mathjax mjx-copytext">$a$</span></mjx-container>, 현재 노드의 왼쪽 자식 노드 <mjx-container class="MathJax" jax="CHTML" style="font-size: 109%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mi class="mjx-i"><mjx-c class="mjx-c1D44F TEX-I"></mjx-c></mjx-mi></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>b</mi></math></mjx-assistive-mml><span aria-hidden="true" class="no-mathjax mjx-copytext">$b$</span></mjx-container>, 현재 노드의 오른쪽 자식 노드 <mjx-container class="MathJax" jax="CHTML" style="font-size: 109%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mi class="mjx-i"><mjx-c class="mjx-c1D450 TEX-I"></mjx-c></mjx-mi></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>c</mi></math></mjx-assistive-mml><span aria-hidden="true" class="no-mathjax mjx-copytext">$c$</span></mjx-container>가 공백으로 구분되어 주어진다. 만약 자식 노드의 번호가 -1인 경우 자식 노드가 없다는 것을 의미한다.</p>
52+
53+
### 출력
54+
55+
<p>유사 중위 순회를 하면서 이동한 총 횟수를 출력한다.</p>
56+
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import Foundation
2+
3+
class FileIO {
4+
@inline(__always) private var buffer: [UInt8] = Array(FileHandle.standardInput.readDataToEndOfFile()) + [0], byteIdx = 0
5+
6+
@inline(__always) private func readByte() -> UInt8 {
7+
defer { byteIdx += 1 }
8+
return buffer.withUnsafeBufferPointer { $0[byteIdx] }
9+
}
10+
11+
@inline(__always) func readInt() -> Int {
12+
var number = 0, byte = readByte(), isNegative = false
13+
while byte == 10 || byte == 32 { byte = readByte() }
14+
if byte == 45 { byte = readByte(); isNegative = true }
15+
while 48...57 ~= byte { number = number * 10 + Int(byte - 48); byte = readByte() }
16+
return number * (isNegative ? -1 : 1)
17+
}
18+
}
19+
20+
let io = FileIO()
21+
22+
let n = io.readInt()
23+
var graph = (1...n).reduce(into: [Int:(Int, Int)]()) { graph, node in
24+
return graph[node] = (-1, -1)
25+
}
26+
27+
(0..<n).forEach { _ in
28+
let root = io.readInt()
29+
let l = io.readInt()
30+
let r = io.readInt()
31+
graph[root] = (l, r)
32+
}
33+
34+
var count = 0
35+
var lastNode = 0
36+
var isMoveFinishied = false
37+
38+
func move(_ node: Int) {
39+
// 1. 현재 위치한 노드의 왼쪽 자식 노드가 존재하고 아직 방문하지 않았다면, 왼쪽 자식 노드로 이동한다.
40+
// 2. 그렇지 않고 현재 위치한 노드의 오른쪽 자식 노드가 존재하고 아직 방문하지 않았다면, 오른쪽 자식 노드로 이동한다.
41+
// 3. 그렇지 않고 현재 노드가 유사 중위 순회의 끝이라면, 유사 중위 순회를 종료한다.
42+
// 4. 그렇지 않고 부모 노드가 존재한다면, 부모 노드로 이동한다.
43+
// 5. 유사 중위 순회를 종료할 때까지 1 ~ 4를 반복한다.
44+
if graph[node]!.0 != -1 {
45+
count += 1
46+
move(graph[node]!.0)
47+
if !isMoveFinishied { count += 1 }
48+
}
49+
if graph[node]!.1 != -1 {
50+
count += 1
51+
move(graph[node]!.1)
52+
if !isMoveFinishied { count += 1 }
53+
}
54+
if node == lastNode {
55+
isMoveFinishied = true
56+
return
57+
}
58+
}
59+
func findLastNode(_ node: Int) {
60+
if graph[node]!.0 != -1 {
61+
findLastNode(graph[node]!.0)
62+
}
63+
lastNode = node
64+
if graph[node]!.1 != -1 {
65+
findLastNode(graph[node]!.1)
66+
}
67+
}
68+
findLastNode(1)
69+
move(1)
70+
print(count)

0 commit comments

Comments
 (0)