Selection Sort (선택 정렬), Insertion Sort (삽입 정렬)
정렬 알고리즘
Bubble Sort에 이어서 선택정렬과 삽입정렬도 마스터해보자. range에 숫자 넣는게 헷갈리는 거만 빼면 상대적으론 쉬운 난이도.
Selection Sort(선택정렬)
- 배열을 순회하면서 i번째 순회에서 숫자를 골라 배열의 i번째 자리에 있는 숫자와 교체하는 방식으로 정렬한다.
- 맨 앞부터 정해진 위치에, 정렬될 원소를 선택하기 때문에 붙여진 이름인 듯
정수 배열 오름차순 정렬하기로 보는 Selection Sort 구현
- 배열의 길이 n, 인덱스를 i라고 할 때, n-1번 돌면서 i번째 돌 때는 i번째 요소부터 순회하며 가장 작은 수를 골라 i번째 요소와 바꾼다.
코드로 구현하기
1 2 3 4 5 6 7 8
| def selection_sort(arr) for i in range(len(arr)-1): lowest = i for j in range(i+1, len(arr)): if arr[lowest] > arr[j]: lowest = j arr[lowest], arr[j] = a[j], a[lowest] return arr
|
- 0부터 배열의 길이 n보다 한 번 적게 돌아가는 for문 안에서, 현재 돌아가는 인덱스 값을 lowest라는 변수에 담은 후 두번째 for문을 돌린다.
- 두번째 for문에서는 j가 하나씩 증가하며 돌아가는데, 이 j를 인덱스값으로 하는 요소가 i, 즉 lowest를 인덱스값으로 하는 요소보다 작으면 lowest 값에 j를 할당한다. 즉 lowest는 항상 순회하면서 가장 작은 값의 인덱스다.
- 두번째 for문이 끝나고 나면 lowest를 인덱스로 갖는 요소와 i를 인덱스로 갖는 값을 서로 바꾼다.
- 앞에서부터 i번째 요소까지는 이미 작업이 수행되어 정렬되었으므로 두번째 for문은 i+1부터 순회하게끔 range를 설정한다.
Selection Sort의 시간복잡도
- 반복문이 두개 중첩되어 있으므로 bubble sort와 같이 O(n2)의 시간복잡도를 갖는다.
- 정확하게는 n*(n-1)/2의 복잡도를 갖는다고 한다.
Insertion Sort (삽입 정렬)
- 앞에서부터 배열을 순회하면서, 순회 중인 인덱스 값의 요소와 바로 앞 요소를 비교하며 정렬하는 정렬
- 그 앞의 요소와 비교하는 조건을 만족하면 그 앞은 이미 정렬된 것과 마찬가지이므로 작업을 멈추고 다음 인덱스로 넘어간다.
정수 배열 오름차순 정렬하기로 보는 Insertion Sort 구현
- 배열의 길이 n, 인덱스를 i라고 할 때, n-1번 두 번째 for문을 돌린다.
- 두 번째 for문은 i+1번째 요소와 i번째 요소를 비교하며, 더 작은 숫자가 앞에 있다는 조건을 충족하면 두번째 for문을 빠져나가 i값을 증가시킨 첫번째 for문으로 돌아간다.
코드로 구현하기
1 2 3 4 5 6 7 8
| def insertion_sort(arr): for i in range(len(arr)-1): for j in range(i+1, 0, -1): if arr[j] < arr[j-1]: arr[j], arr[j-1] = arr[j-1], arr[j] else: break return arr
|
- 첫번째 for문은 데이터의 길이보다 한 번 적게 반복문이 실행된다.
- 두번째 for문은 i+1의 인덱스값을 갖는 수부터 그 전의 요소와 비교하여 자신보다 작은 값이 나올 때까지 교체한다.
- 이미 작은 값을 앞에서부터 넣어주었기 때문에 자신보다 작은 값을 만나면 그 앞은 정렬되어있다고 보고 두번째 for문을 빠져나간다.
Insertion Sort의 시간복잡도
- 반복문이 두개 중첩되어 있으므로 bubble sort와 같이 O(n2)의 시간복잡도를 갖지만, 완전정렬된 최선의 경우 O(n)의 시간복잡도를 갖는다.
느낀 점
- range 안에 들어가는 숫자가 헷갈렸는데 일단 정렬의 모든 바깥 for문은 데이터의 전체 길이보다 1번 적은 턴을 돈다는 것을 잘 기억해야겠다.
- 거품정렬과 삽입정렬은 break가 있기 때문에 최선의 경우 시간복잡도가 O(n)까지 된다는 것이 인상깊다.
참고자료
hanana1253문정동에서 코딩하는 하나나입니다.