본문 바로가기
코딩테스트/이코테

[CH6 정렬] 기준에 따라 데이터를 정렬 (2)

by 의정부핵꿀밤 2021. 12. 29.
728x90

선택 정렬

  • 처리되지 않은 데이터 중에서 가장 작은 데이터를 선택하여 맨 앞에 있는 데이터와 바꾸는 것을 반복한다
  • 이 방법은 가장 원시적인 방법으로 매번 '가장 작은 것을 선택한다'는 의미에서 '선택 정렬'이라고 불린다
  • 정렬 알고리즘에서는 흔히 데이터의 개수를 N이라고 표현한다

 

다음 예제를 통해 N=10인 경우를 살펴보자

이 때 회색 카드는 '현재 정렬되지 않은 데이터 중에서 가장 작은 데이터'를 의미하고, 하늘색 카는 '이미 정렬된 카드'를 의미한다

 

 

선택 정렬의 단계별 설명

위의 카드를 선택 정렬 알고리즘을 통해 정렬해보자!

 

STEP 0

STEP 0) 초기 단계에서는 모든 데이터가 정렬되어 있지 않으므로, 전체 중에서 가장 작은 데이터를 선택한다 (0)

따라서 선택한 0과 맨 앞에 있는 데이터 7의 자리를 바꾼다

 

 

STEP 1

STEP 1) 이제 정렬된 첫번쨰 데이터는 제외하고 그 뒤의 데이터 중에서 가장 작은 데이터인 1을 선택하여 이를 처리되지 않은 데이터 중 가장 앞에 있는 데이터 5와 자리를 바꾼다

 

 

STEP 2

STEP 2) 이제 정렬된 데이터를 제외하고 정렬되지 않은 데이터 중에서 가장 작은 데이터인 2를 선택하고, 처리되지 않은 데이터 중 가장 앞에 있는 데이터 9와 자리를 바꾼다

 

 

STEP 3

STEP 3) 정렬된 데이터를 제외하고 정렬되지 않은 데이터 중에서 가장 작은 데이터인 3을 선택하고, 이를 처리되지 않은 데이터 중 가장 앞에 있는 데이터 7과 자리를 바꾼다


STEP 9

STEP 9) 앞의 과정을 계속해서 반복하면 위의 그림처럼 맨 마지막 데이터만 남는다. 하지만 남은 데이터는 위 과정을 수행해도 자리는 바뀌지 않으므로 이 단계에서는 정렬을 수행하지 않고 끝내면 된다

 


선택 정렬 소스코드

이처럼 선택 정렬은 가장 작은 데이터를 앞으로 보내는 과정을 N-1번 반복하면 정렬이 완료된다

이제 파이썬과 C++ 코드로 선택 정렬을 구현해보자!

 

파이썬 코드)

array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]

for i in range(len(array)):
    min_index = i #가장 작은 원소의 인덱스

    for j in range(i+1, len(array)):
        if array[min_index] > array[j]:
            min_index = j

    array[i], array[min_index] = array[min_index], array[i] #스와프

print(array)

중첩 반복문을 사용하여 구현하였다

이 때 파이썬에서 스와프는 위처럼 해주면 된다

 

파이썬 선택정렬 결과화면

 

C++ 코드)

#include <algorithm>
#include <iostream>

using namespace std;

int main()
{
    int n = 10;
    int arr[10] = {7, 5, 9, 0, 3, 1, 6, 2, 4, 8};
    
    for(int i=0;i<n;i++)
    {
        int min_index = i;
        
        for(int j=i+1;j<n;j++)
        {
            if(arr[min_index] > arr[j])
            {
                min_index = j;
            }
        }
        swap(arr[i],arr[min_index]);
    }
    
    for(int i=0;i<n;i++)
    {
        cout<<arr[i]<<" ";
    }

    return 0;
}

C++에서도 파이썬과 거의 동일하게 작성해주면 된다

C++에서는 #include <algorithm> 라이브러리에 swap 함수를 지원하기 떄문에 이를 사용하여 스와프하면 된다!

 

C++ 선택정렬 알고리즘


선택 정렬의 시간 복잡도

이제 선택 정렬의 시간 복잡도를 계산해보자

선택 정렬은 N-1번만큼 가장 작은 수를 찾아서 맨 앞으로 보내야 한다

또한 매번 가장 작은 수를 찾기 위해서 비교 연산이 필요하다

구현 방식에 따라서 사소한 오차는 있을 수 있지만 앞쪽의 그림대로 구현하면 연산 횟수는 다음과 같다

N + (N-1) + (N-2) + ... + 2

따라서 근사치로 N*(N+1)/2 번의 연산을 수행한다고 하면, 빅오 표기법에 따라 O(N^2)이라고 표현할 수 있다

 

선택 정렬 알고리즘을 다른 알고리즘과 비교해보면 매우 비효율적인 것을 알 수 있다

(파이썬 기준)

데이터의 개수(N) 선택 정렬 퀵 정렬 기본 정렬 라이브러리
N=100 0.0123초 0.00156초 0.00000753초
N=1000 0.354초 0.00343초 0.0000365초
N=10000 15.475초 0.0312초 0.000248초

위처럼 선택 정렬 알고리즘은 다른 알고리즘에 비해 매우 비효율적이다

하지만 특정한 리스트에서 가장 작은 데이터를 찾는 일이 코딩테스트에서 잦으므로 선택 정렬 소스코드에 익숙해질 필요는 있다

728x90

댓글