리스트 안에 있는 중간 값을 선택한다. 이렇게 고른 값은 피벗(Pivot)이라고 한다.
피벗을 기준으로 피벗보다 작은 요소들은 모두 피벗의 Left로 옮겨지고 피벗보다 큰 요소들은 모두 피벗의 Right로 옮겨진다.
피벗을 제외한 왼쪽 리스트와 오른쪽 리스트를 다시 정렬한다.
부분 리스트들이 더 이상 분할이 불가능할 때까지 반복한다.
(리스트의 크기가 0이나 1이 될때까지 반복한다.)
재귀함수란?
- 함수가 직접 또는 간접적으로 자신을 호출하는 프로세스를 재귀함수라고 한다.
- 사용자가 설정한 종료시점을 도달하기 전까지 계속해서 자기 자신의 메서드를 반복한다.**
public List<Integer> merge(List<Integer> left,List<Integer> mid,List<Integer> right){
List<Integer> answer = new ArrayList<>();
answer.addAll(left);
answer.addAll(mid);
answer.addAll(right);
return answer;
}
if(arr.size()<=1) return arr;
int pivot = arr.get(arr.size()/2);
for(int i=0; i<arr.size(); i++){
if(arr.get(i)<pivot){
left.add(arr.get(i));
}else if(arr.get(i)>pivot)
right.add(arr.get(i));
else
mid.add(arr.get(i));
}
return merge(sort(left),mid,sort(right));
// 재귀함수를 통한 퀵 정렬
public class QuickSort {
public List<Integer> merge(List<Integer> left,List<Integer> mid,List<Integer> right){
List<Integer> answer = new ArrayList<>();
answer.addAll(left);
answer.addAll(mid);
answer.addAll(right);
return answer;
}
public List<Integer> sort(List<Integer> arr){
// 재귀 탈출 조건
if(arr.size()<=1) return arr; // mid보다 값이 모두 작거나 커서 한쪽으로 쏠려 한쪽에는 아예 들어가지 않는 경우도 생기고
// 1개의 값만 들어가는 경우도 생긴다. 1개만 들어가면 더이상 비교를 할 수 없기에 1이하로 하여 재귀를 빠져나오도록 한다.
// 1. 기준값 뽑는 로직 구현
int pivot = arr.get(arr.size()/2); // index = 4 , arr[4] = 5
// 2. 기준값 기준으로 왼쪽 오른쪽으로 나누어 담는 로직 구현
List<Integer> left = new ArrayList<>();
List<Integer> right = new ArrayList<>();
List<Integer> mid = new ArrayList<>();
for(int i=0; i<arr.size(); i++){
if(arr.get(i)<pivot){
left.add(arr.get(i));
}else if(arr.get(i)>pivot)
right.add(arr.get(i));
else
mid.add(arr.get(i));
}
// list를 합치는 연산
return merge(sort(left),mid,sort(right));
}
public static void main(String[] args) {
int[] arr = {20,18,5,19,5,25,40,50}; // 8
List<Integer> al = new ArrayList<>();
for(int i =0; i<arr.length; i++){
al.add(arr[i]);
}
QuickSort q = new QuickSort();
System.out.println(q.sort(al));
}
}
1st
입력 값 : {20,18,5,19,5,25,40,50}
pivot = arr[4] = 5
left = {}
mid = {5,5}
right={20,18,19,25,40,50}
left값이 없으므로 mid값을 merge로 보내 answer 리스트에 저장
answer = [5,5]
right값으로 재귀 진행 - - - - 2st
2st
입력 값 :{20,18,19,25,40,50}
pivot = arr[3] = 25
left = {20,18,19}
mid = {25}
right = {40,50}
left값으로 재귀 진행 ---- 2st_(1)
2st_(1)의 재귀가 끝나면 mid값을 answer 리스트에 저장
answer = [5,5,18,19,20,25]
right값으로 재귀 진행 ---- 2st_(2)
2st_(1)
입력 값 : {20,18,19}
pivot = arr[2] = 19
left = {18}
mid = {19}
right = {20}
left와 right모두 1개씩 있으므로 더 이상 재귀 진행 불가
따라서 merge로 left -> mid -> right 순으로 값 전송하여 answer 리스트에 저장
answer = [5,5,18,19,20]
2st_(2)
입력 값 :{40,50}
pivot = arr[1] = 50
left = {40}
mid = {50}
right = {}
left는 1개만 있으므로 더 이상 재귀 진행 불가
따라서 merge로 left -> mid 순으로 값을 전송하여 answer 리스트에 저장
answer = [5,5,18,19,20,25,40,50]