package collection.compare;
import java.util.Arrays;
public class SortMain1 {
public static void main(String[] args) {
Integer[] array = {3, 2, 1};
System.out.println(Arrays.toString(array));
System.out.println("기본 정렬 후");
Arrays.sort(array);
System.out.println(Arrays.toString(array));
}
}
실행 결과
[3, 2, 1]
기본 정렬 후
[1, 2, 3]
Arrays.sort()를 사용하면 배열에 들어있는 데이터를 순서대로 정렬할 수 있음


지금 설명한 정렬은 가장 단순한 정렬의 예시임
자바는 초기에는 퀵소트를 사용했다가 지금은 데이터가 작을 때(32개 이하)는 듀얼 피벗 퀵소트(Dual-Pivot QuickSort)를 사용하고, 데이터가 많을 때는 팀소트를 사용함
quick_sort(int[] list, int left, int right) {
if (left < right) {
int pivot = partition(list, left, right);
quick_sort(list, left, pivot-1);
quick_sort(list, pivot+1, right);
}
}

- 배열의 임의의 원소를 pivot, 가장 첫 번째 원소를 low, 가장 마지막 원소를 high라고 지정
- low 값이 pivot보다 작을 동안 low의 인덱스를 증가시킴
- 반복문이 계속될 때까지 조건에 부합하는 원소들은 pivot의 오른족 부분 리스트가 됨
- high 값이 pivot보다 클 동안 high 인덱스를 감소시킴
- 반복문이 계속될 때까지 조건에 부합하는 원소들은 pivot의 오른쪽 부분 리스트가 됨
- 2와 3의 반복문을 탈출하여 도달한 위치는 각각 low 값이 pivot보다 크고, high 값이 pivot보다 작은 경우이므로 이때 멈춘 두 원소 자리를 교환함
- low와 high의 위치가 엇갈리지 않을 때까지 2~3 과정을 반복함
- low와 high의 위치가 엇갈리는 때 high와 pivot의 자리를 교환함
- 최종적으로 pivot의 위치를 기준으로 왼쪽에는 pivot보다 작은 원소들이, 오른쪽에는 pivot보다 큰 원소들이 위치하게 됨
피봇 1개를 기준으로 삼아 정렬하는 퀵 정렬에서, 피봇 2개를 기준으로 정렬하는 알고리즘
임의의 피봇 2개를 기준으로 pivot1보다 작은 부분, pivot1 ~ pivot2 사이의 부분, pivot2보다 큰 부분으로 나눈 뒤 각 부분을 다시 듀얼 피봇 퀵정렬 방법으로 정렬함
pivot2는 항상 pivot1보다 크도록 설정해야 함
Tim Peter에 의해 고안된 Merge Sort, Insertion Sort이 혼용된 하이브리드 정렬 알고리즘
삽입 정렬의 작은 데이터 세트에 대해 효율적인 면과 병합 정렬의 큰 데이터 세트에 효율적인 면을 합친 것임
팀 정렬은 배열을 여러 부분으로 나눔
run이라고 하며, 각 run에서는 삽입 정렬로 정렬함run들은 병합 정렬로 합치면서 정렬함이렇게 작은 부분에서는 삽입 정렬을 큰 부분에서는 병합 정렬을 이용해 각 정렬들의 강점을 활용하여 정렬함

public interface Comparator<T> {
int compare(T o1, T o2);
}
package collection.compare;
import java.util.Arrays;
import java.util.Comparator;
public class SortMain2 {
public static void main(String[] args) {
Integer[] array = {3, 2, 1};
System.out.println(Arrays.toString(array));
System.out.println("Comparator 비교");
Arrays.sort(array, new AscComparator());
System.out.println("AscComparator:" + Arrays.toString(array));
Arrays.sort(array, new DescComparator());
System.out.println("DescComparator:" + Arrays.toString(array));
Arrays.sort(array, new AscComparator().reversed()); //DescComparator와 같다
System.out.println("AscComparator.reversed:" + Arrays.toString(array));
}
static class AscComparator implements Comparator<Integer> {
@Override
public int compare(Integer o1, Integer o2) {
System.out.println("o1=" + o1 + " o2=" + o2);
return (o1 < o2) ? -1 : ((o1 == o2) ? 0 : 1);
}
}
static class DescComparator implements Comparator<Integer> {
@Override
public int compare(Integer o1, Integer o2) {
System.out.println("o1=" + o1 + " o2=" + o2);
return (o1 < o2) ? -1 : ((o1 == o2) ? 0 : 1) * -1;
}
}
}
실행 결과
[3, 2, 1]
Comparator 비교
o1=2 o2=3
o1=1 o2=2
AscComparator:[1, 2, 3]
o1=2 o2=1
o1=3 o2=2
DescComparator:[3, 2, 1]
o1=3 o2=2
o1=2 o2=1
AscComparator.reversed:[3, 2, 1]
Arrays.sort()를 사용할 때 비교자를 넘겨주면 알고리즘에서 어떤 값이 더 큰지 두 값을 비교할 때, 비교자를 사용함Arrays.sort(array, new AscComparator())
Arrays.sort(array, new DescComparator())
AscComparator를 사용하면 숫자가 점점 올라가는 오름차순으로 정렬됨
DescComparator를 사용하면 숫자는 점점 내려가는 내림차순으로 정렬됨
DescComparator구현의 마지막에 -1을 곱해주었기 때문에 이렇게 하면 양수는 음수로, 음수는 양수로 반환됨정렬을 반대로
new AscComparator().reversed()
정렬을 반대로 하고 싶으면 reversed() 메서드를 사용하면 됨
비교자(Comparator)를 사용하면 정렬의 기준을 자유롭게 변경할 수 있음
강의 출처 : 김영한의 실전 자바 - 중급 2편
정렬 알고리즘 자료 출처 : [Algorithm] 퀵 정렬(Quick Sort)과 듀얼 피봇 퀵 정렬(Dual Pivot Quick Sort)