Skip to content

Commit

Permalink
post/algorithm/course/21(1/3)
Browse files Browse the repository at this point in the history
  • Loading branch information
ensia96 committed Sep 21, 2021
1 parent 36d22ec commit 377f3ff
Showing 1 changed file with 42 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,62 +27,72 @@ tags:
> 그리고, 이러한 점화식들은 알고리즘이 동작하는 방식에 따라서 여러 가지 형태를 띠었다.
- 물론, 지금까지의 수업에서는 이러한 점화식들을 모두 직접 전개하는 방식으로 풀어왔다.
- 하지만, 이번 수업에서는, 지금까지와는 다르게, 그림을 이용해 개념적으로 풀어볼 것이다.
- 하지만, 이번 수업에서는, 지금까지와는 다르게, 그림을 그려, 개념적으로 풀어볼 것이다.

## 1-1. 이진 탐색 알고리즘

첫 번째로 살펴볼 것은, 바로 이전 수업에서 살펴봤던 이진 탐색 알고리즘에 대한 점화식이다.

```
T(n) = T(n/2) + c, T(1) = c
T(n) = T(n / 2) + c, T(1) = c
```

> 이를 재귀적인 관점 대신, '문제의 크기가 절반으로 줄어든다.' 라는 직관적인 관점에서 살펴보자.
> 재귀적인 관점 대신, '문제의 크기가 절반으로 줄어든다.' 라는 직관적인 관점에서 살펴보자.
<br>
### 1-1-1. 가정

이 때, n 크기의 문제가 계속해서 n/2 크기의 문제로 나뉘므로, n = 2^k 라고 가정할 것이다.
이 때, n 크기의 문제가 계속해서 (n / 2) 크기의 문제로 나뉘므로, n = 2^k 라고 가정할 것이다.

- 물론, 무조건 2^k 일 필요는 없다. 왜냐하면, 빅오 표기법의 결과가 같을 것이기 때문이다.
- 물론, 빅오 표기법의 특성상 결과는 같을 것이므로, n의 값이 무조건 2^k 일 필요는 없다.
- 하지만, n을 2로 k번 나누면 1이 되는 간단한 식을 유도하기 위해, 이렇게 가정하는 것이다.

<br>

그러면, 이것을 T(n/2) 대신에, T(n/2^2) + c 처럼 계속 대입을 해서 T(1) 에 도달할 때까지 계속 반복해도 되지만, 그림으로 그리면, 더 직관적으로 이해하기 쉽다.

무슨 말이냐면, 우선 n이 있다.

n은 n/2 로 쪼개진다.

그러면서, +c 만큼의 일을 하는 것이다.

그러면, +c 를 c만큼 일을 하는 것이다.

n/2 짜리 문제가 n/2^2 짜리 문제로 쪼개지고, 거기서 c만큼의 일을 또 해야 한다.(연산이 필요한 것이다.)
### 1-1-2. 그림으로 표현하기

그 다음에 이를 계속 반복하는 것이다.
그림을 그리면서 점화식을 풀면, 알고리즘의 동작 원리를 더 직관적으로 확인할 수 있다.

그러다가, n/2^k 까지 내려갈 것이다.

그러면, n/2^k 까지 내려가면서 c만큼의 일을 하고, T(n/2^k) 값은 c다.
```
n -> (n / 2) + c -> (n / 2^2) + c -> ... -> (n / 2^k) + c
```

그러면 결국은, n 문제가 반쪽 짜리 문제가 되는데, c만큼의 연산을 해서 반쪽 짜리 문제가 되었고, 또 그것의 반쪽짜리 문제가 되는데, 또 c만큼을 투자한 것이다.
- 문제의 크기가 절반으로 줄어들 때마다, 상수 횟수(c) 만큼의 추가 연산이 필요하다.
- 그 문제가 다시 절반 크기로 줄어들 때도, 상수 횟수(c) 만큼의 추가 연산이 필요하다.
- 이러한 과정을 계속해서 반복하다 보면, 결국, 문제의 크기는 (n / 2^k) 이 될 것이다.
- 현재, n = 2^k 이라고 가정한 상황이므로, T(n / 2^k) = T(n / n) = T(1) = c 가 된다.

결국, n ~ n/2^k 까지 내려오면서 생긴 c를 다 더하면 되는 것이다.
### 1-1-3. 수행 시간 파악하기

그러면 이 c가 몇 개냐 하면, n이 몇 번 내려 갔는가? k번 내려갔다.
문제의 크기가 점화식의 일반항과 같아졌으니, 이제, 추가 연산의 횟수만 파악하면 된다.

k번 내려갔는데, 그러면 c가 몇 개냐면, k개 생기는 것이다.
```
n
(n / 2) + c ┐
↓ │
(n / 2^2) + c │
↓ ├ k ┐
... │ │
↓ │ ├ (k + 1)
(n / 2^k) + c ┘ │
↓ │
c ────────────────┘
```

그래서 결국, 각각 반씩 내려가면서 발생했던 기본 연산 횟수 c를 다 합치면, kc가 된다.
- 문제의 크기가 줄어든 횟수는 k번이므로, 상수 횟수(c) 의 추가 연산도 k번 수행된다.
- 따라서, T(n / 2^k) 의 수행 시간까지 고려하면, 전체 수행 시간은 c * (k + 1) 이 된다.

그래서, T(n) = kc 가 되는데, 마찬가지로 n = 2^k 의 양변에 로그를 취해서, k = log2(n) 이라는 것을 알고 있는 것이고, 그러면, 결국은 O(k) 가 되는 것이고, c는 상수이기 때문에, k는 log2(n) 이니까, O(log n) 이 되는 것이다.
### 1-1-4. 정리

즉, log2(n) 번만 비교하면, 이진 탐색을 할 수 있다는 것이다.
여기서, n = 2^k 의 양변에 로그를 취하면, k = log2(n) 이 되므로, T(n) = O(log n) 이 된다.

정렬이 되어있다는 것을 잘 이용한 것이다.
```
T(n) = c * (k + 1) = c * (log2(n) + 1) = O(log n)
↘ ↗
n = 2^k => k = log2(n)
```

그렇지 않고, a[0] 부터 차례대로 비교했으면, 최악의 경우에는 n번을 비교해야 되는데, 정렬이 되어있기 때문에, log2(n) 번 만으로도 내가 원하는 값이 있는지 없는지 알 수 있다는 것이다.
- 다시 말해, 이진 탐색 알고리즘은 log2(n) 번의 비교 연산을 통해 수행된다는 뜻이다.
- 앞에서부터 하나씩 비교해야 하는 상황이었다면, n번의 비교 연산이 필요했을 것이다.
- 하지만, 탐색 대상이 정렬된 상태라는 사실을 잘 이용해, 비교 횟수를 줄일 수 있었다.

## 1-2. Quick Select 알고리즘의 최선의 경우

Expand Down

0 comments on commit 377f3ff

Please sign in to comment.