QuickSort with Javascript에 대한 Big O 질문

Viet

저는 QuickSort로 작업하고 있으며이 문제 에 대해 LeetCode에서이 두 가지 알고리즘을 테스트했습니다 . 두 알고리즘 모두 작동하지만 하나는 다른 알고리즘보다 훨씬 빠르며 그 이유를 이해할 수 없습니다.

이것은 LeetCode의 시간 제한을 초과합니다.

function quickSort(array) {
    quickSortHelper(array, 0, array.length - 1);
    return array;
}

function quickSortHelper(array, start, end) {
    // Edge case
    if(start >= end) return;
    // Always choose the pivot index at the beginning of the array.
    const pivot = start;
    // The left index is next to the pivot on the right.
    let left = start + 1;
    let right = end;

    while (right >= left) {
        if (array[left] > array[right] && array[right] < array[pivot])
            swap(left, right, array);
        if (array[left] < array[pivot]) left += 1;
        if (array[right] > array[pivot]) right -= 1;
    }

    swap(pivot, right, array);

    // Always sort the smaller sub-array first
    const leftIsSmaller = right - 1 - start < end - (right + 1);

    if (leftIsSmaller) {
        quickSort(array, start, right - 1);
        quickSort(array, right + 1, end);
    }
    else {
        quickSort(array, right + 1, end);
        quickSort(array, start, right - 1);
    }
}

function swap(a, b, array) {
    [array[a], array[b]] = [array[b], array[a]];
    return array;
}

빅 O :

  • 최악 : 시간 = O (n ^ 2) 왜냐하면 피벗이 정렬되지 않은 부분의 끝으로 계속 바뀌면 O (n-1) ~ O (n) 매번 = O (n * n)
  • 최상 : 시간 = O (nlog (n)) 피벗이 어레이를 2 개로 분할 할 때.
  • 평균 : 시간 = O (nlog (n))
  • Space = O (log (n)) 2 개의 하위 배열이있는 재귀와 더 작은 하위 배열에 대해 먼저 빠른 정렬이 이루어지기 때문입니다.

이것은 LeetCode 시간 제한을 초과하지 않으며 대부분의 제출물보다 훨씬 빠릅니다. 큰 while 루프 안에있는 2 개의 while 루프는 (나에게) 느리게 보이지만 실제로는 더 빠릅니다.

function quickSort(array) {
    sortHelper(array, 0, array.length - 1);
    return array;
}

function sortHelper(array, start, end) {
    if (start >= end) return;
    let i = start;
    let j = end;
    let base = array[i];

    while (i < j) {
        while (i < j && array[j] >= base) j -= 1; // This makes sense but why this while loop has to happen before the other while loop?
        array[i] = array[j]; // this line
        while (i < j && array[i] <= base) i += 1;
        array[j] = array[i]; // and this line. don't they make you lose access to the values in the array?
    }
    array[i] = base;
    sortHelper(array, start, i - 1);
    sortHelper(array, i + 1, end);
}

왜 그런 겁니까?

Tricot

시간 복잡도에는 차이가 없지만 첫 번째 버전은 종종 동일한 (또는 반대) 데이터 비교를 두 번 이상 수행합니다. 이것은 두 번째 버전에서는 발생하지 않습니다.

예를 들어, 다음 if의 경우 첫 번째 표현식이 true이고 두 번째는 false이며 여러 번 반복하는 동안이 표현식이 있다고 가정합니다 .

 if (array[left] > array[right] && array[right] < array[pivot])

... left이 첫 번째 표현식이 참일 때 한 반복에서 다음 반복으로 변경되지 않는 점을 감안할 때이 첫 번째 표현식을 여러 번 확인하는 것은 정말 낭비입니다 .

이 극단적 인 예제 어레이를 예로 들어 보겠습니다. [1, 6, 3, 2, 5, 4]

피벗은 1입니다.

모든 반복 동안 right인덱스는 왼쪽에 도달 할 때까지 감소합니다. 반복 당 비교 횟수는 4 회이므로 5 회 반복하면 20 회가됩니다.

이제 더 빠른 알고리즘을 살펴보십시오. 동일한 입력에 대한 비교 횟수는 첫 번째 내부 루프의 경우 5이고 두 번째 내부 루프의 경우 0입니다 ( 데이터 비교 만 계산 합니다 ).

이것은 극단적 인 예 (20 대 5)이지만 더 많은 무작위 입력에서도 덜 발생합니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

ObjectPooling에 대한 질문

분류에서Dev

Bash에 대한 질문

분류에서Dev

chroot에 대한 질문

분류에서Dev

Lucene에 대한 질문

분류에서Dev

Snap에 대한 질문

분류에서Dev

코드에 대한 Big O 설명

분류에서Dev

배낭에 대한 Big O의 정의

분류에서Dev

while 루프에 대한 Big-O?

분류에서Dev

C 배열 구문에 대한 질문

분류에서Dev

Java 용 중첩 if 문에 대한 질문

분류에서Dev

if 문 형식에 대한 질문

분류에서Dev

Polymer에 대한 간단한 질문

분류에서Dev

Polymer에 대한 간단한 질문

분류에서Dev

sudo su에 대한 간단한 질문-

분류에서Dev

OpenStack에 Rally 설치에 대한 질문

분류에서Dev

TensorFlow mnist 데이터 재구성 질문에 대한 질문

분류에서Dev

병합 두 정렬 목록에 대한 질문 (leetcode 질문 21)

분류에서Dev

시간 복잡도 O (1), O (n), O (log n), O (n log n)에 대한 질문

분류에서Dev

JavaScript의 변수에 대한 빠른 멍청한 질문

분류에서Dev

Promise를 사용한 비동기 JavaScript에 대한 질문

분류에서Dev

Kotlin Coroutine 취소에 대한 질문

분류에서Dev

R의 최적화에 대한 질문

분류에서Dev

np.logical_and 사용에 대한 질문

분류에서Dev

Emeditor의 열 편집에 대한 질문

분류에서Dev

미디어 쿼리에 대한 질문

분류에서Dev

Vulkan VkSubpassDependency 멤버에 대한 질문

분류에서Dev

Cloud SQL에 대한 기본 질문

분류에서Dev

password_hash에 대한 질문

분류에서Dev

MVC 패턴 이해에 대한 질문?