Skip to content

Commit

Permalink
Docs: Add Doit_Algorithm_Coding/Chapter04.md
Browse files Browse the repository at this point in the history
  • Loading branch information
fkdl0048 committed Nov 5, 2024
1 parent 34cb218 commit e616c3d
Showing 1 changed file with 185 additions and 1 deletion.
186 changes: 185 additions & 1 deletion Doit_Algorithm_Coding/Chapter04.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,189 @@ int main()

삽입 정렬은 이미 정렬된 데이터 범위에 정렬되지 않은 데이터를 적절한 위치에 삽입해 정렬하는 방식이다. 시간 복잡도는 O(n^2)이지만, 구현하기 쉽다.

#### ATM 인출 시간 계산하기
### 퀵 정렬

퀵 정렬은 기준값을 선정해 해당 값보다 작은 데이터와 큰 데이터와 큰 데이터로 분류하는 것을 반복해 정렬하는 알고리즘이다. 기준값이 어떻게 선정되는지가 시간 복잡도에 많은 영향을 미치고 평균 시간 복잡도는 O(nlogn)이다. 최악의 경우 시간 복잡도는 O(n^2)이다.

#### K번째 수 구하기

```cpp
#include <iostream>
#include <vector>
using namespace std;

void quickSort(vector<int> &A, int S, int E, int K);
int partition(vector<int> &A, int S, int E);
void swap(vector<int> %A, int i, int j);

int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);

int N, K;
cin >> N >> K;
vector<int> A(N);

for (int i = 0; i < N; i++)
cin >> A[i];

quickSort(A, 0, N - 1, K);
cout << A[K - 1];
}

void quickSort(vector<int> &A, int S, int E, int K)
{
int pivot = partition(A, S, E);
if (pivot == k) {
return;
}
else if (k < pivot) {
quickSort(A, S, pivot - 1, K);
}
else {
quickSort(A, pivot + 1, E, K);
}
}

int partition(vector<int> &A, int S, int E)
{
if (S + 1 == E) {
if (A[S] > A[E])
swap(A, S, E);
return E;
}

int M = (S + E) / 2;
swap(A, S, M);
int pivot = A[S];
int i = S + 1, j = E;

while (i <= j) {
while (j >= S + 1 && A[j] > pivot) {
j--;
}
while (i <= E && A[i] < pivot) {
i++;
}
if (i < j) {
swap(A, i, j);
}
else {
break;
}
}

A[S] = A[j];
A[j] = pivot;
return j;
}

void swap(vector<int> &A, int i, int j)
{
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
```
### 병합 정렬
병합 정렬은 분할 정복 방식을 사용해 데이터를 분할하고 분할한 집합을 정렬하며 합치는 알고리즘이다. 시간 복잡도는 O(nlogn)이다.
2개의 그룹을 병합하는 과정은 투 포인터의 원리로 코딩테스트에서 두 배열을 한 배열로 합치는 문제에서도 사용된다.
#### 수 정렬하기 2
```cpp
#include <iostream>
#include <vector>
using namespace std;
void mergeSort(int S, int E);
static vector<int> A;
static vector<int> B;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int N;
cin >> N;
A.resize(N + 1);
B.resize(N + 1);
for (int i = 1; i <= N; i++)
cin >> A[i];
mergeSort(1, N);
for (int i = 1; i <= N; i++)
cout << A[i] << '\n';
}
void mergeSort(int S, int E)
{
if (S == E)
return;
int M = (S + E) / 2;
mergeSort(S, M);
mergeSort(M + 1, E);
int i = S, j = M + 1, k = S;
while (i <= M && j <= E)
{
if (A[i] <= A[j])
B[k++] = A[i++];
else
B[k++] = A[j++];
}
while (i <= M)
B[k++] = A[i++];
while (j <= E)
B[k++] = A[j++];
for (int i = S; i <= E; i++)
A[i] = B[i];
}
```

### 기수 정렬

기수 정렬은 값을 비교하지 않는 특이한 정렬이다. 기수 정렬은 값을 놓고 비교할 자릿수를 정한 다음 해당 자릿수만 비교한다. 기수 정렬의 시간 복잡도는 O(kn)으로 k는 자릿수의 최대값이다.

#### 수 정렬하기 3

```cpp
#include <iostream>
using namespace std;

int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);

int N;
cin >> N;
int A[10001] = { 0 };

for (int i = 0; i < N; i++)
{
int num;
cin >> num;
A[num]++;
}

for (int i = 1; i <= 10000; i++)
{
for (int j = 0; j < A[i]; j++)
cout << i << '\n';
}
}
```

0 comments on commit e616c3d

Please sign in to comment.