2750. 수 정렬하기






문제

N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오.

입력

첫째 줄에 수의 개수 N(1<=N<=1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 숫자가 주어진다. 이 수는 절대값이 1,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.

출력

첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.

예제 입력 

5
5
2
3
4
1

예제 출력 

1
2
3
4
5





1. 거품 정렬 소개


삽입 정렬 다음으로 간단한 정렬 알고리즘을 소개하고자 한다.


마찬가지로 인간의 정렬 방법과 유사한 알고리즘이다. 삽입 정렬에선 가지고 있는 숫자 타일을 하나 내려놓고, 정렬하고 했다면,


이번에는 가지고 있는 숫자 타일 중 가장 큰 수 부터 내려놓는 방법이다.



그러면 가장 큰 수는 어떻게 찾을까? 당연히 전체를 다 뒤져야 한다.


여러 방법이 있겠지만, 거품 정렬에선 이름 처럼 거품이 떠오르는 듯한 방법을 쓴다.


1) 맨 앞의 두 인자를 비교해서(인덱스 0과 1), 올바른 순서면 바꾸지 않고, 아니라면 서로 바꾼다. (swap)


2) 이번엔 다음 두 인자를(인덱스 1, 2) 마찬가지로 비교하고 스왑한다.


3) 배열의 마지막 두 인자 까지 2)를 수행한다.



다 수행했으면 배열의 상태는 어떠할까? 중간 인자들의 상태는 뒤죽박죽일지 몰라도 가장 마지막 숫자는 올바른 위치에 있다.


오름차순으로 정렬하기로 했다면, 배열 중 가장 큰수가 가장 맨 마지막에 있게 되는 것이다.



이제 제대로 박힌 마지막 인자를 제외하고 다시 처음부터 과정을 반복하면 된다.


그러면 뒤에서 부터 올바른 위치로 인자들이 채워지는 것이다.


애니메이션으로 확인해보자.



뒤에서 부터 한 점씩 채워지는 과정을 눈으로 확인할 수 있다.



2. 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <vector>
using namespace std;
 
int n, tmp;
vector<int> v;
 
int main() {
    scanf("%d"&n);
    for (int i = 0; i < n; ++i) {
        scanf("%d"&tmp);
        v.push_back(tmp);
    }
 
    for (int i = n - 2; i >= 0--i) {
        for (int j = 0, k = 1; j <= i; ++j, ++k) {
            if (v[j] > v[k]) {
                tmp = v[j];
                v[j] = v[k];
                v[k] = tmp;
            }
        }
    }
 
    for (int i = 0; i < n; ++i)
        printf("%d\n", v[i]);
 
    return 0;
}
cs



3. 시간 복잡도


삽입 정렬과의 차별점은, 삽입 정렬이 for문 안이 while문으로 되어있다면, 거품 정렬은 for문으로 되어있다는 점이다.


따라서 삽입 정렬은 운이 좋다면 while문이 별로 돌지 않고 끝날 수 있지만,

거품 정렬은 그런거 없고 무조건 for문을 다 돌아야 한다.



또한 최악의 경우 마찬가지로 이중for문으로 인해 시간복잡도는 O(n ^ 2)이다.

'알고리즘 > 정렬 알고리즘' 카테고리의 다른 글

5. 카운팅 정렬 counting sort  (0) 2017.09.27
4. 힙 정렬 heap sort  (0) 2017.09.27
3. 병합 정렬 merge sort  (0) 2017.09.25
1. 삽입 정렬 insertion sort  (0) 2017.09.25

+ Recent posts