합병 정렬과 같은 가정으로 작동한다.
퀵 정렬에서는 피벗을 어떻게 정하느냐가 속도에 영향을 준다. 이상적으로 데이터셋의 중간값을 선택하면 좋다. 그러나 정렬해야할 데이터가 어떤지는 알 수 없다. 첫번재 요소, 마지막 요소, 가운데 요소, 랜덤 요소 등으로 선택할 수 있다.
function pivot(arr, start=0, end=arr.length+1){
function swap(array, i, j) { // 스왑함수
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
var pivot = arr[start]; // 피벗을 배열 첫째 요소로 한다.
var swapIdx = start; // 스왑인덱스는 0부터 시작
for(var i = start + 1; i < arr.length; i++){
if(pivot > arr[i]){ // 루프를 돌면서 요소가 피벗보다 작으면
swapIdx++; // 스왑인덱스를 +1 하고
swap(arr,swapIdx,i); // 스왑인덱스와 해당 요소를 스왑. 즉 앞으로 보낸다.
}
}
swap(arr,start,swapIdx); // 피벗(start=0)을 제 위치로 스왑
return swapIdx;
}
function quickSort(arr, left = 0, right = arr.length -1){
if(left < right){ // 두개가 같아지면 요소가 하나라는 뜻.
let pivotIndex = pivot(arr, left, right) //3
quickSort(arr,left,pivotIndex-1); // 피벗의 왼쪽을 넣음
quickSort(arr,pivotIndex+1,right); // 피벗의 오른쪽도
}
return arr; // 반환.
}
quickSort([100,-3,2,4,6,9,1,2,5,3,23])
최선의 경우 → O(n log n)
최악의 경우 → O(n^2)
평균의 경우 → O(n log n)
공간복잡도 → O(log n)
배열의 길이가 2배 늘어나면 분할이 1회 늘어남. log n.
각각 분해하는 단계마다 O(n)번 비교를 수행. 피벗을 찾을때.
피벗을 첫번째 값으로 할때 최악의 경우. 이미 오름차순으로 정렬된 데이터.
두가지로 나뉘지 않는다. 늘 모든 값이 피벗보다 크므로 사실상 이중 반복문과 같다.
따라서 피벗을 첫번째 값으로 하지 말고, 차라리 랜덤으로 하는 것이 낫다. 또는 매번 중간에 있는 값을 고른다.
이렇게 하면 최악의 경우를 피할 수 있다.