안녕하세요, 여행벌입니다.
오늘은 선택 정렬(selection sort)에 대해서 포스팅해보겠습니다.
선택 정렬이란
'정렬되지 않은 데이터에서 가장 작은 값을 뽑아 가장 앞의 데이터와 교환 해나가는 정렬 방식' 입니다.
EX)
바로 예시를 통해서 익혀보겠습니다.
[ 2 8 6 1 5 3 4 7 ] 8개의 숫자가 담긴 배열을 선택 정렬을 이용해서 정렬해보겠습니다.
STEP 1]
아직까지는 정렬된 부분이 하나도 없기 때문에 전체 범위에서 가장 작은 값인 1을 찾을 수 있습니다.
정렬되지 않은 가장 앞부분은 '2' 이므로 '2' 와 '1'을 SWAP 하게 됩니다.
STEP 2]
이제 정렬된 부분은 [ 1 ] 정렬되지 않은 부분은 [ 8 6 2 5 3 4 7 ] 이 되고, 정렬되지 않은 부분에서 가장 작은 값인 2를 가장 앞 '8'과 SWAP 합니다.
STEP 3]
이 과정을 반복하면 다음과 같이 됩니다.
STEP 4]
STEP 5]
STEP 6]
STEP 7]
정렬되지 않은 배열에 원소가 하나만 남아있다면, 그 원소가 가장 큰 원소이므로 STEP 8 까지 진행하지 않고 정렬을 종료할 수 있습니다.
코드 구현
코드는 다음과 같습니다.
void SelectionSort(int arr[], int N) {
int min, temp;
for(int i = 0; i < N - 1; i++) {
min = i; // min 에 unsorted 중 가장 작은 값을 저장한다.
for(int j = i+1; j < N; j++)
if(arr[j] < arr[min]) min = j;
// 가장 앞과 SWAP 해준다.
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
첫 번째 for 문의 i 는 정렬되지 않은 배열의 가장 앞을 가리킵니다.
두 번째 for 문은 이제 정렬되지 않은 배열에서 가장 작은 값을 찾는 역할을 합니다.
복잡도 분석
이제 N 개의 원소가 있다고 가정하고 선택 정렬의 복잡도를 분석해보겠습니다.
첫 번째 원소를 정렬하기 위해 N개의 모든 원소를 순회하며 가장 작은 값을 찾아야 합니다.
즉, N - 1 번의 비교 연산이 발생합니다.
두 번째 원소를 정렬하기 위해서는 ( N - 1 )개의 모든 원소를 순회하며 가장 작은 값을 찾아야 합니다.
즉, N - 2 번의 비교 연산이 발생합니다.
그다음은 ( N - 2 ) 개의 모든 원소를 순회하며 가장 작은 값을 찾아야 하고
이 과정을 반복하면 총 (N - 1) + ( N - 2 ) + ⋯ + 1 번 비교 연산이 발생합니다.
등차수열의 합으로 O ( N ^ 2 ) 의 시간 복잡도를 가지는 것을 확인할 수 있습니다.
배열이 이미 정렬이 되어있더라도 가장 작은 값을 찾기 위해 항상 똑같은 순회, 비교 과정을 거치므로
최선, 평균, 최악의 경우에 대해서 시간 복잡도가 동일하게 O ( N ^ 2 )이 됩니다.
불안정 정렬
선택 정렬은 다음과 같은 상황에서 동일한 원소의 위치가 뒤바뀌므로 불안정 정렬에 속합니다.
[ 5 5 1 ] 배열을 선택 정렬을 통해서 정렬해보겠습니다.
이때 동일한 원소 5가 존재하므로 5-1 / 5-2 로 구분해주겠습니다.
결과는 다음과 같습니다.
정렬 전 [ 5-1 5-2 1 ] → 정렬 후 [ 1 5-2 5-1 ]
동일한 원소가 존재할 때, 동일한 원소 간의 순서가 선택 정렬을 진행한 후 바뀐 것을 확인할 수 있습니다.
따라서, 선택 정렬은 '불안정 정렬' 입니다.
이상으로 선택 정렬 포스팅을 마치겠습니다.
'Computer Science > Algorithm' 카테고리의 다른 글
[알고리즘] 삽입 정렬(insertion sort) 란 - travelbeeee (1) | 2019.12.30 |
---|---|
[알고리즘] 버블 정렬(bubble sort) 란 - travelbeeee (0) | 2019.12.27 |
[알고리즘] 문자배열을 이용한 큰 수 덧셈 - travelbeeee (2) | 2019.12.26 |
[알고리즘] 고속 거듭제곱 연산 - travelbeeee (0) | 2019.10.01 |
[알고리즘] 다이나믹프로그래밍을 활용한 구간의 합 구하기 (0) | 2019.09.30 |