[알고리즘-기초] 선택(Selection) 정렬

2023. 3. 31. 17:08·Algorithm/Basic

선택(Selection) 정렬


선택 정렬은 말 그대로 현재 위치에 들어갈 데이터를 찾아 선택하는 알고리즘이다.

 

좀더 정확하게 말하자면 무작위 데이터 중 가장 작은 데이터를 선택해 맨 앞에 있는 데이터와 바꾸고, 그 다음 작은 데이터를 선택해 앞에서 두 번째 데이터와 바꾸는 과정을 반복하는 것이다.

 

데이터를 '비교'하면서 찾기 때문에 '비교 정렬'이며 정렬의 대상이 되는 데이터 외에 추가적인 공간을 필요로 하지 않기 때문에 '제자리 정렬(in-place sort)'이기도 하다. 정확히는 데이터를 서로 교환하는 과정(swap)에서 임시 변수를 필요로 하나, 이는 충분히 무시할 만큼 적은 양이기 때문에 제자리 정렬로 보는 것이다.

그리고 '불안정 정렬'이다. 

 

특성 설명
In-place 알고리즘 Memory 상에서 필요 시 상호 위치만 변경될 뿐 추가적인 배열 생성이 불 필요함
Unstable 알고리즘 Stable을 보장할 수 없다. 그 이유는 아래에 설명

 




정렬 방법

 

선택 정렬의 과정은 다음과 같다.

 

  1. 주어진 리스트에서 최솟값을 찾는다.
  2. 최솟값을 맨 앞 자리의 값과 교환한다.
  3. 맨 앞 자리를 제외한 나머지 값들 중 최솟값을 찾아 위와 같은 방법으로 반복한다. 

 

즉, 그림으로 보면 다음과 같은 과정을 거친다.

 

 

마지막 round 9 를 안하는 이유는 앞 인덱스부터 순차적으로 정렬해나가기 때문에 "N개의 데이터 중 N-1개가 정렬 되어있다"는 것은 결국 마지막 원소가 최댓값이라는 말이다. 이는 정렬이 되어있다는 상태이므로 굳이 정렬해줄 필요 없다.

 

 

전체적인 흐름을 보면 다음과 같다.

https://en.wikipedia.org/wiki/Selection_sort

 

https://ko.wikipedia.org/wiki/선택_정렬

 

 

그 외에도 많은 참고 영상들이 있는데, 영상으로 보는 것이 더 쉬울 것 같아 같이 첨부하도록 하겠다.

 

Selection Sort 구현하기

public class SelectionSort {

    public static void sort(int[] arr) {

        for (int i = 0; i < arr.length - 1; i++) {
            int min_indx = i;

            // 최솟값을 갖고있는 인덱스 찾기
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[min_indx] > arr[j]) {
                    min_indx = j;
                }
            }
            
            // i번째 값과 찾은 최솟값을 서로 교환
            swap(arr, min_indx, i);
        }

        System.out.println(Arrays.toString(arr));
    }

    public static void swap(int[] arr, int a, int b) {
        int tmp = arr[a];
        arr[a] = arr[b];
        arr[b] = tmp;
    }


    public static void main(String[] args) {
        int[] arr = {5, 3, 7, 1, 6};
        sort(arr);
    }
}

 

선택 정렬 장단점

 

[장점]

1. 추가적인 메모리 소비가 작다.

 

[단점]

1. 시간복잡도가 O(N^2) 이다.

2. 안정 정렬이 아니다.

 

 

단점에 대해 짚고 넘어가보자.

 

먼저 첫 번째 단점이다. 기본적으로 선택정렬은 O(N^2)의 시간복잡도(time complexity)를 보인다.

 

공식을 유도해보자면 이렇다. 

N이 정렬해야하는 리스트의 자료 수, i가 교환되는 인덱스라고 할 때 loop(반복문)을 생각해보자.

 

i=1  일 때, 데이터 비교 횟수는 N-1 번

i=2 일 때, 데이터 비교 횟수는 N-2 번

i=3 일 때, 데이터 비교 횟수는 N-3 번

                   ⋮

i=N-1 일 때, 데이터 비교 횟수는 1 번

 

즉, 다음과 같이 공식화 할 수 있다.

 

그리고 모든 N에 대하여 다음을 만족하기 때문에 시간복잡도 또한 도출 할 수 있다.

 

 

물론 Bubble Sort 와 이론상 같은 시간복잡도를 갖음에도 비교 수행이 상대적으로 적기 때문에 조금 더 빠르긴 하나 그럼에도 좋은 알고리즘은 아니다.

 

알고리즘 시간복잡도(최상) 시간복잡도(평균) 시간복잡도(최악) 공간복잡도
선택 정렬 O(n^2) O(n^2) O(n^2) O(1)

 

두 번째 단점은 안정 정렬이 아니라는 것이다. 즉, Stable 하지 않다는 것. 간단한 예를 들어보겠다.

우리는 다음과 같은 배열을 정렬하고자 한다.

 

[B1, B2, C, A]     (A < B < C)

 

주의해서 볼 점은 B에 붙어있는 숫자는 임의로 붙인 숫자다. 즉, B1 과 B2는 같은 숫자다.

 

그럼 순서대로 순회하면서 교환한다면 이렇다.

round 1 : [A, B2, C, B1]

round 2 : [A, B2, C, B1]

round 3 : [A, B2, B1, C]

 

이렇게 초기의 B1 B2의 순서가 뒤 바뀐 것을 볼 수 있다.

 

이러한 상태를 불안정 정렬이라고 하는데 문제가 되는 이유는 예로들어 학생을 관리하고자 할 때, 성적순으로 나열하되, 성적이 같으면 이름을 기준으로 정렬하고 싶다고 할 때. 즉, 정렬 규칙이 다수이거나 특정 순서를 유지해야 할 때 문제가 될 수 있다.

 

[(가영, 60), (가희, 60), (찬호, 70), (동우, 45)] 이렇게 리스트가 존재한다고 생각해보자. 성적순이되, 성적이 같다면 이름순으로 정렬해야 한다고 했다.

 

그러면 보통 이름을 일단 정렬을 해놓을 것이다.

 

<이름 정렬 순>

[(가영, 60), (가희, 60), (동우, 45), (찬호, 70)]

 

그 다음에 '성적 순'으로 정렬 할 것이다. 만약 선택 정렬을 하면 어떻게 되는지 보자.

round 1 : [(동우, 45), (가희, 60), (가영, 60), (찬호, 70)]

round 2: [(동우, 45), (가희, 60), (가영, 60), (찬호, 70)]

round 3: [(동우, 45), (가희, 60), (가영, 60), (찬호, 70)]

 

이렇게 '가희'보다 '가영'이 앞에 있어야 함에도 순서가 바뀌어 버린 것을 볼 수 있다.

 

 

 

 

 

정리

 

선택 정렬의 경우 정렬 알고리즘의 기초다보니 대부분 거품 정렬(Bubble Sort), 삽입 정렬(Insertion Sort) 과 함께 많이 배운다. 물론 성능상 좋지는 못하더라도 이러한 알고리즘들을 확실하게 익혀야 좀 더 고급스러운 정렬들을 이해 할 수 있다.

 

테스트 한 결과 selection sort는 5초대에 자리하고 있다. (컴퓨터의 환경에 따라 달라질 수 있다) 이후에 아래 알고리즘들을 모두 구현해볼 것이다.

 

또한 각 정렬 알고리즘 별 시간 복잡도와 평균 정렬 속도는 다음과 같다.

 

 

 

 


참고

  • https://evan-moon.github.io/2018/10/13/sort-algorithm/
  • https://velog.io/@mng051/%EB%8C%80%ED%91%9C%EC%A0%81%EC%9D%B8-%EC%A0%95%EB%A0%AC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98#%EC%82%BD%EC%9E%85-%EC%A0%95%EB%A0%AChttps://hongjw1938.tistory.com/28
  • https://st-lab.tistory.com/195
'Algorithm/Basic' 카테고리의 다른 글
  • [알고리즘-기초] 셸(Shell) 정렬
  • [알고리즘-기초] 삽입(Insertion) 정렬
  • [알고리즘-기초] 버블(Bubble) 정렬
  • [알고리즘-기초] 정렬 (개요)
s_y_130
s_y_130
  • s_y_130
    About SY
    s_y_130
  • 전체
    오늘
    어제
    • 분류 전체보기 (436) N
      • JAVA (54)
        • 더 자바 8 (0)
        • JAVA (41)
        • JAVA (JVM) (13)
      • Computer Science (86)
        • CS Basic (7)
        • OOP (11)
        • Design Pattern (16)
        • Network (8)
        • HTTP (6)
        • WEB (22)
        • OS (16)
      • DataBase (29)
        • DB theory (15)
        • MySQL (14)
        • Redis (0)
      • Collection Framework (1)
        • 구현 (1)
      • Data Structure (14)
        • Linear (9)
        • Non-Linear (5)
      • Algorithm (19)
        • Basic (12)
        • 응용 (2)
        • 완전 탐색(Brute Force) (1)
        • 다익스트라 (1)
        • Algorithm Problem (3)
      • Spring (104)
        • 스프링 핵심 원리 - 기본편 (9)
        • 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (7)
        • 스프링 MVC 2편 - 백엔드 웹 개발 핵심 기술 (11)
        • 스프링 DB 1편 - 데이터 접근 핵심 원리 (6)
        • 스프링 DB 2편 - 데이터 접근 활용 기술 (10)
        • 스프링 핵심 원리 - 고급편 (13)
        • 스프링 부트 - 핵심 원리와 활용 (9)
        • Spring Security 6.x (2)
        • Spring Batch (2)
        • Spring Cloud로 개발하는 MSA (1)
        • 재고시스템으로 알아보는 동시성이슈 해결방법 (4)
        • 개념 (27)
        • 테스트 (0)
        • Annotation (1)
        • Error Log (2)
      • TEST (0)
        • 부하 테스트 (0)
        • Practical Testing: 실용적인 테스트.. (0)
      • JPA (40)
        • 자바 ORM 표준 JPA 프로그래밍 (12)
        • 1편- 실전! 스프링 부트와 JPA 활용 (7)
        • 2편- 실전! 스프링 부트와 JPA 활용 (4)
        • 실전! 스프링 데이터 JPA (6)
        • 실전! Querydsl (6)
        • 개념 (5)
      • 백엔드 부트캠프[사전캠프] (35)
        • TIL (12)
        • 문제풀이 (23)
      • 백엔드 부트캠프 (5) N
        • Calculator (3)
        • Kiosk (2) N
      • Open Source (0)
      • Book Study (1)
        • Morden Java in Action (1)
        • Real MySQL 8.0 Vol.1 (0)
        • TDD : By Example (0)
      • AWS (0)
        • EC2 (0)
      • git (2)
      • AI (22)
        • Machine Learning (17)
        • Deep Learning (0)
        • TensorFlow (1)
        • PyTorch (1)
        • YOLO (1)
        • Data Analysis (0)
        • Ai code Error (1)
        • Numpy (1)
      • MY (0)
      • WEB (15)
        • Django (3)
        • WEB 개념 (1)
        • React (1)
        • Maven (10)
      • Python (6)
      • 기초수학 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
s_y_130
[알고리즘-기초] 선택(Selection) 정렬
상단으로

티스토리툴바