
퀵 정렬은 기본적으로 재귀를 사용해서 데이터를 쪼개고, 배열이 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));