퀵 정렬
은 기본적으로 재귀를 사용해서 데이터를 쪼개고, 배열이 0개나 1개의 요소를 가지면 각자 정렬된 배열이 된다는 점을 이용해서 정렬을 했던 병합 정렬
과 같은 가정에서 출발한다.
피봇 포인트
라고 부르는 기준점을 선택하여 작업을 한다. 해당 숫자보다 작은 숫자를 모두 왼쪽으로 옮기고, 그 숫자보다 큰 숫자들은 모두 오른쪽으로 옮기는 일이다.퀵 정렬은 분할정복 방법을 통해 리스트를 정렬한다.
피벗
이라고 한다.분할
이라고 한다. 분할을 마친 뒤에 피벗은 더 이상 움직이지 않는다.재귀
는 리스트의 크기가 0이나 1이 될 때까지 반복된다.병합 정렬을 구현하려면 먼저 피벗의 양쪽에 있는 배열의 요소를 배열하는 기능을 담당하는 함수를 구현하는 것이 유용하다.
피벗보다 작은 모든 값을 피벗의 왼쪽으로 이동시키고, 피벗보다 큰 모든 값을 피벗의 오른쪽으로 이동하도록 배열의 요소를 재정렬한다.
- 피벗의 양쪽에 있는 요소의 순서는 중요하지 않다.
헬퍼함수는 새 배열을 만들지 않고 기존 배열에 대해서 작업을 한다.
완료되면 헬퍼 함수는 피벗의 인덱스를 반환한다.
피벗 선택
- 배열, 시작 인덱스 및 끝 인덱스의 세 가지 인수를 받아들이는 데 도움이 됩니다(각각 기본값은 0이고 배열 길이는 1이 될 수 있음)
- 배열의 시작 부분에서 피벗을 잡습니다.
- 현재 피벗 인덱스를 변수에 저장합니다(피벗이 끝나는 위치를 추적합니다).
- 처음부터 끝까지 배열을 반복합니다.
- 피벗이 현재 요소보다 크면 피벗 인덱스 변수를 증가시킨 다음 현재 요소를 피벗 인덱스에 있는 요소로 바꿉니다.
- 시작 요소(예: 피벗)를 피벗 인덱스로 교체
- 피벗 인덱스 반환
function pivot(arr, start = 0, end = arr.length - 1) {
const swap = (arr, idx1, idx2) => {
[arr[idx1], arr[idx2]] = [arr[idx2], arr[idx1]];
};
// 피봇이 항상 첫 번째 요소라고 가정
let pivot = arr[start];
let swapIdx = start;
for (let i = start + 1; i <= end; i++) {
if (pivot > arr[i]) {
swapIdx++;
swap(arr, swapIdx, i);
}
}
swap(arr, start, swapIdx);
return swapIdx;
}
console.log(pivot([4, 8, 2, 1, 5, 7, 6, 3]));
/* for 루프
[4, 8, 2, 1, 5, 7, 8, 3] i 1, arr[1] 8, swapIdx 0
[4, 2, 8, 1, 5, 7, 8, 3] i 2, arr[2] 2, swapIdx 1 (8), 2<->8
[4, 2, 1, 8, 5, 7, 8, 3] i 3, arr[3] 1, swapIdx 2 (8), 1<->8
[4, 2, 1, 8, 5, 7, 8, 3] i 4, arr[4] 5, swapIdx 2
[4, 2, 1, 8, 5, 7, 8, 3] i 5, arr[5] 7, swapIdx 2
[4, 2, 1, 8, 5, 7, 8, 3] i 6, arr[6] 8, swapIdx 2
[4, 2, 1, 3, 5, 7, 8, 8] i 7, arr[7] 3, swapIdx 3(8), 3 <-> 8
swap(arr, 0, 3)
[3, 2, 1, 4, 5, 7, 8, 8] 3<->4 */
- 배열에서 피벗 도우미 호출
- 피벗 헬퍼 함수가 업데이트된 피벗 인덱스를 반환하면 해당 인덱스의 왼쪽에 있는 하위 배열과 해당 인덱스의 오른쪽에 있는 하위 배열에서도 피벗 헬퍼 함수를 재귀적으로 호출한다.
- 이러한 작업은 요소가 2개 미만인 하위 배열에서 발생한다.
function quickSort(arr, left = 0, right = arr.length - 1) {
if (left < right) {
let pivotIndex = pivot(arr, left, right); // 위에서 정의한 헬퍼 함수 사용
// left
quickSort(arr, left, pivotIndex - 1);
// right
quickSort(arr, pivotIndex + 1, right);
}
return arr;
}
console.log(quickSort([4, 6, 9, 1, 2, 5, 3]));
// [4,6,9,1,2,5,3]
// [3,2,1,4,6,9,5]
// 4
// 3,2,1 6,9,5
// 3 6
// 2,1 5 9
// 2
// 1
function quickSort(arr) {
if (arr.length <= 1) {
return arr;
}
const pivot = arr[0];
const left = [];
const right = [];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return quickSort(left).concat(pivot, quickSort(right));
}
const data = [50, 100, 38, 48, 58, 29, 38, 49];
console.log(quickSort(data));