일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 30 |
- C언어 포인터
- github
- c#
- 구조체
- docker
- 포인터
- c# 추상 클래스
- Flutter
- c# winform
- Python
- jupyter lab
- Data Structure
- jupyter
- dart 언어
- 플러터
- C++
- 다트 언어
- c언어
- c# 윈폼
- Unity
- 도커
- git
- C# delegate
- HTML
- gitlab
- Algorithm
- Houdini
- 깃
- 유니티
- vim
- Today
- Total
nomad-programmer
[Programming/Algorithm] 선택 정렬(Selection Sort) 본문
선택 정렬은 버블 정렬보다도 쉽고 간단한 알고리즘이다. 선택 정렬은 정렬순서에 맞게 하나씩 선택해서 옮기는, 옮기면서 정렬이 되게 하는 알고리즘이다.
정렬순서상 가장 앞서는 것을 선택해서 가장 왼쪽으로 이동시키고, 원래 그 자리에 있던 데이터는 빈 자리에 가져다 놓는다.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
void SelSort(int arr[], int n) {
int maxIdx;
int temp;
for (int i = 0; i < n - 1; i++) {
maxIdx = i;
// 최솟값 탐색
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[maxIdx]) {
maxIdx = j;
}
}
// 교환
temp = arr[i];
arr[i] = arr[maxIdx];
arr[maxIdx] = temp;
}
}
int main() {
int arr[4] = { 3, 4, 2, 1 };
SelSort(arr, sizeof(arr) / sizeof(int));
for (int i = 0; i < 4; i++) {
cout << arr[i] << ' ';
}
cout << endl;
return 0;
}
/* 결과
1 2 3 4
*/
선택 정렬(Selection Sort): 성능평가
선택 정렬의 코드만 봐도 버블 정렬과 성능상 큰 차이가 없음을 알 수 있다. 그럼 비교횟수의 확인을 위해 선택 정렬의 일부인 다음 반복문을 보자.
for(int i=0; i<n-1; i++){
maxIdx = i;
for(int j=i+1; j<n; j++){
if(arr[j] < arr[maxIdx]){
maxIdx = j;
}
}
...
}
위의 코드에서 바깥쪽 for문의 i가 0일 때 안쪽 for문의 j는 1부터 n-1까지 증가하여 선택 정렬의 비교 연산은 n-1회 진행된다. 그리고 바깥쪽 for문의 i가 1일 때는 안쪽 for문의 j가 2부터 n-1까지 증가하여 선택 정렬의 비교연산은 n-2회 실행된다. 즉 비교연산의 횟수는 다음과 같이 정리가 가능하다.
(n-1) + (n+2) + ... + 2 + 1
그런데 이는 버블 정렬의 경우와 똑같다. 따라서 선택 정렬의 빅-오 역시 최악의 경우와 최선의 경우 구분 없이 다음과 같다.
O(n의 2제곱)
언뜻 생각하기엔 버블 정렬보다 나은 성능을 보장할 것처럼 보였는데, 비교횟수를 기준으로 보면 차이가 없음을 알 수 있다. 그렇다면 데이터의 이동횟수도 버블 정렬과 차이가 없을까? 여기에는 제법 차이가 있다.
버블 정렬이나 선택 정렬이나 데이터의 교환을 위한 세 번의 대입 연산이 다음과 같은 유형으로 진행된다.
temp = A;
A = B;
B = temp;
하지만 존재하는 위치가 다르다. 버블 정렬의 경우에는 안쪽 for문에 속해있다. 반면 선택 정렬의 경우에는 바껕쪽 for문에 속해있다. 때문에 선택 정렬의 경우 n-1회의 교환이 이뤄지므로 데이터의 이동횟수는 이의 세 배인 3(n-1)이 된다. 따라서 선택 정렬의 데이터 이동연산에 대한 빅-오는, 최악의 경우와 최선의 경우 구분 없이 다음과 같다.
O(n)
최악의 경우를 놓고 보면 버블 정렬보다 선택 정렬에 좋은 성능을 기대할 수 있겠지만, 버블 정렬은 최선의 경우에 단 한 번의 데이터 이동도 발생하지 않는다는 점과, 실제로 데이터들이 늘 최악의 상황으로 배치되지는 않는다는 사실을 감안하면, 이 둘의 우열을 가리는 것은 무의미하다고 할 수 있다.
'Programming > Algorithm' 카테고리의 다른 글
[Programming/Algorithm] 힙 정렬(Heap Sort) (0) | 2021.03.09 |
---|---|
[Programming/Algorithm] 삽입 정렬(Insertion Sort) (0) | 2021.03.08 |
[Programming/Algorithm] 버블 정렬(Bubble Sort) (0) | 2021.03.08 |
[Programming/Algorithm] 우선순위 큐와 Heap 자료구조 (0) | 2021.03.07 |
[Programming/Algorithm] 퀵 정렬(Quick Sort) with Python (0) | 2021.02.10 |