삽입 정렬은 필요할 때만 각 데이터를 적절한 위치에 삽입하는 정렬이다.
손 안의 카드를 정렬하는 방법과 유사하며, 무조건 위치를 교환하는 선택 정렬과 버블 정렬에 비해 다소 효율적이라고 볼 수 있다.
오름차순을 기준으로 정렬한다
원소가 n개 있다고 가정
public void insertionSort() {
int[] arr = new int[] {11, 7, 5, 6, 10, 9};
//0번째 인덱스는 비교대상이 없으므로 1번쨰 인덱스부터 시작
for (int i=1; i<arr.length; i++){
int tmp = arr[i]; // 정렬방식에 따라 삽입될 숫자를 tmp 변수로 복사
//0~i-1번 인덱스까지는 정렬된 상태이므로, i번 인덱스까지 포함돼서 0~i번 정렬되도록 j를 i-1부터 0까지로 설정
int j;
for(j=i-1; i>=0; i--){
if(arr[j] > tmp) arr[j+1] = arr[j]; // tmp가 들어갈 위치를 찾기 위해 tmp보다 큰 수를 오른쪽으로 옮긴다.
else break; // tmp보다 작은 수가 들어있는 인덱스를 만나면 정지
}
arr[j + 1] = tmp; // tmp보다 작은 수가 들어있는 인덱스의 바로 뒤에 tmp를 넣는다.
}
}
i는 삽입하게 될 원소 인덱스이다. 삽입 정렬은 두 번째 인덱스부터 시작한다.
j는 i번째 인덱스의 원소를 삽입하기 위해 비교할 인덱스 번호이다. 0번 인덱스 ~ (i-1)번 인덱스까지는 정렬된 상태이다. 이 중에서 tmp보다 작은 원소를 만나게 되면 해당 원소 앞에 tmp가 삽입된다.
11 7 5 6 10 9
첫 번째 원소인 11은 비교대상이 없으므로 1번 인덱스 원소인 7부터 시작한다.
1 + 2+ 3 + ... + (n-2) + (n-1) = n*(n-1)/2
= n * n
= O(n*n)
n개의 자료가 들어있는 배열을 삽입 정렬로 정렬하는 데에 걸리는 시간은 O(n^2)이다.
같은 시간복잡도를 가지는 선택,버블 정렬에 비해 필요할 때에만 삽입을 한다는 점에서 연산 수가 적어 비교적 효율적인 정렬 방식이다.
주어진 배열 안에서 교환을 통해 정렬이 수행되므로 O(n)이다.
https://yjg-lab.tistory.com/162?category=956502
https://gmlwjd9405.github.io/2018/05/06/algorithm-insertion-sort.html