퀵 정렬 (Quick Sort) - Java
by mignon25퀵 정렬이란?
- 시간복잡도 : O(NlogN)
- Divide and Conquer 방식
- Divide 단계
- pivot(기준점)을 기준으로 왼쪽엔 더 작은 값, 오른쪽엔 더 큰 값을 위치하게 한 후 Partitioning
- pivot 은 왼쪽 값, 중간 값, 오른쪽 값 세 가지로 지정할 수 있다.
- Conquer 단계
- 나누어진 각각을 정렬
- Divide 단계부터 진행 => 재귀적으로 진행된다.
- Combine : 이미 pivot 을 기준으로 왼쪽은 더 작고, 오른쪽은 더 큰 값만 들어있으므로 합치기만 하면 된다.
partition 하기 (pivot 을 오른쪽 끝 값으로 설정하는 경우)
int partition(int[] my_list, int start, int end) {
// partition 로직
return b;
}
// b : big 그룹의 시작
(my_list 의 타입은 배열이나 컬렉션 편한대로 지정해도 될 것 같다.)
- my_list : 정렬해야 하는 배열
- start, end : partition 하려는 범위를 나타낸다. (인덱스 값)
파티션을 하기 위해 먼저 네 개의 그룹으로 나누어 생각할 수 있다.
- Pivot 값
- Small 그룹 : Pivot 보다 작은 값을 가지는 그룹
- Big 그룹 : Pivot 보다 큰 값을 가지는 그룹
- Unknown 그룹 : 아직 Pivot 값과 비교하지 않은 그룹

변수
- start : partition 하는 범위의 시작점
- end : partition 하는 범위의 끝점 = p (pivot 값과 동일하다)
- b : Big 그룹의 시작
- i : Unknown 그룹의 시작
Partition 진행과정
1. 시작
- b, i 는 가장 왼쪽 인덱스를 가리킨다.
- 아직 pivot 과 비교하기 전이므로 pivot 값을 제외한 나머지는 모두 Unknown 그룹에 속한다.

2. 비교 대상이 pivot 값 보다 큰 경우
- 16은 pivot 7 보다 크다. => big 그룹 => i 만 오른쪽으로 한 칸 이동

3. 비교 대상이 pivot 값보다 작은 경우
- 세번째 요소 6의 경우 pivot 값보다 작다.
=> smal 그룹 에 들어가야 한다.
=> b가 가리키는 값과 i 가 가리키는 값의 자리를 바꾼다.
=> b와 i 모두 오른쪽으로 한 칸씩 이동



4. i 가 pivot 값의 위치로 왔을 때 (i == end)
- pivot 값과 b 의 요소 자리를 바꾼다.
=> pivot 왼쪽은 모두 pivot 보다 작은 값이, pivot 오른쪽은 모두 pivot 보다 큰 값이 위치한 상태


5. pivot 의 인덱스 리턴(b)
Partition 함수 구현
import java.util.Arrays;
public class Partition {
public static void swap(int[] myList, int index1, int index2) {
int tmp = myList[index1];
myList[index1] = myList[index2];
myList[index2] = tmp;
}
public static int partition(int[] myList, int start, int end) {
int b = start;
int i = start;
int p = end;
while(i <= end) {
if(i == end) {
swap(myList, b, p);
break;
}
else if(myList[i] > myList[p]){
i++;
}
else {
swap(myList, i, b);
i++;
b++;
}
}
// pivot 인덱스 리턴 : pivot 의 위치가 b가 되었으므로 b 리턴
return b;
}
public static void main(String[] args) {
int[] myList = {6, 1, 2, 6, 3, 5, 4};
System.out.println(Arrays.toString(myList)); // 파티션 전
int pivot = partition(myList, 0, myList.length - 1);
System.out.println(pivot); // pivot 값
System.out.println(Arrays.toString(myList)); // 파티션 후
}
}
// 출력 결과
[6, 1, 2, 6, 3, 5, 4]
3
[1, 2, 3, 4, 6, 5, 6]
Quick Sort 구현
public class QuickSort {
public static void swap(int[] myList, int index1, int index2) {
int tmp = myList[index1];
myList[index1] = myList[index2];
myList[index2] = tmp;
}
public static int partition(int[] myList, int start, int end) {
int b = start;
int i = start;
int p = end;
while(i <= end) {
if(i == end) {
swap(myList, b, p);
break;
}
else if(myList[i] > myList[p]){
i++;
}
else {
swap(myList, i, b);
i++;
b++;
}
}
// pivot 인덱스 리턴 : pivot 의 위치가 b가 되었으므로 b 리턴
return b;
}
public static void quicksort(int[] myList, int start, int end) {
// base case
if(start >= end) {
return;
}
int pivot = partition(myList, start, end);
quicksort(myList, start, pivot - 1);
quicksort(myList, pivot, end);
}
public static void main(String[] args) {
int[] myList = {28, 13, 9, 30, 1, 48, 5, 7, 15};
System.out.println(Arrays.toString(myList)); // 퀵정렬 전 myList
quicksort(myList, 0, myList.length - 1);
System.out.println(Arrays.toString(myList)); // 퀵정렬 후 myList
}
}
// 출력 결과
[28, 13, 9, 30, 1, 48, 5, 7, 15]
[1, 5, 7, 9, 13, 15, 28, 30, 48]
'Algorithm' 카테고리의 다른 글
| 기수 정렬 (Radix Sort) - Java (0) | 2023.03.31 |
|---|---|
| 삽입 정렬 (Insert Sort) - Java (0) | 2023.03.31 |
| DFS - 전위 순회, 중위 순회, 후위 순회 (0) | 2023.03.24 |
| [BFS] 최단 경로 출력하기 (Java) (0) | 2023.03.22 |
| [DFS] 부분 집합 모두 출력하기 (Java) (0) | 2023.03.21 |
블로그의 정보
Mignon'S Dev Log
mignon25