


- 실행 시간이 입력 데이터의 배치와 무관하다.
: 데이터가 정렬/역순/랜덤 이든 어차피 n-1번까지 for문을 돌고 1번의 swap과정이 일어나기에 입력데이터의 배치가 다르다고 실행시간이 달라지는 것은 아니다.
- 데이터 이동이 최소화된다.
: swap 과정이 삽입 정렬과는 달리 비교 1 챕터 당 1번만 일어난다.
- 제자리 정렬
: 합병정렬처럼 부가적인 저장공간이 필요없다는 뜻이다.
public class SelectionSort extends AbstractSort {
public static void sort(Comparable[] a){
int N = a.length;
for(int i = 0; i<N; i++) {
int min = i;
for( int j = i+1; j<N; j++ ){
if(less(a[j],a[min]))
min=j;
}
swap(a, i, min);
}
assert isSorted(a);
}
}

그러나 이건 "최악"의 경우이지, 최선의 경우의 수는 O(n)
그러나 최선의 경우 (입력 배열이 이미 정렬이 되어 있는 경우)
-> 교환 자체가 일어나지 않으므로 0 의 성능을 자랑
- 실행 시간이 입력 데이터의 초기 배치에 따라 결정
: 이미 정렬된 경우(최선)와 역순으로 정렬된 경우(최악)이 각각 O(N^2)과 0O(N) 으로 큰 차이가 남
public class InsertionSort extends AbstractSort {
public static void sort(Comparable[] a){
int i,j;
for(i=1; i<a.length; i++){
Comparable next = a[i]; //comparable 인터페이스를 구현하는 객체라면, 뭐든지 받을 수 있음
for(j=i-1; j>=0 && less(next,a[j]); j--){ //next( a[i] ) < (a[i-1) => 내림차순임
a[j+1] = a[j]; //a[j+1]은 Comparable next에 값 저장되어 있음.
}
a[j+1] = next;
}
}
}

public class InsertionSort extends AbstractSort {
public static void sort(Comparable[] a){
int N = a.length;
for(int i=1; i<N; i++){
for(int j=i; j>0 && less(a[j],a[j-1]); j--){ //less함수가 true면, 현재 내림차순이란 의미
swap(a, j, j-1);
}
}
assert isSorted(a); //해당 함수가 true가 아니면 exception 발생
}
}

쉘 정렬은 해당 문제점을 보완하기 위해 h개 만큼 떨어진 원소들과 비교 후 자리를 바꾼다
=> 즉, 한 번의 연산으로 h만큼 이동 이 가능하다!
=> 즉 h만큼 이동하는 삽입정렬이란 뜻 (실제 코드도 비슷함)
: h번째 항목들은 정렬된 배열
