왜 mergesort O (log n)입니까?


27

Mergesort는 나누기와 정복 알고리즘이며 입력이 반복적으로 반으로 줄어듦에 따라 O (log n)입니다. 그러나 입력이 각 루프에서 절반이 되더라도 각 절반의 배열에서 스와핑을 수행하기 위해 각 입력 항목을 반복해야하므로 O (n)이 아니어야합니까? 이것은 본질적으로 무의식적으로 O (n)입니다. 가능한 경우 예제를 제공하고 작업을 올바르게 계산하는 방법을 설명하십시오! 아직 아무것도 코딩하지 않았지만 온라인에서 알고리즘을 살펴 보았습니다. 또한 wikipedia에서 mergesort의 작동 방식을 시각적으로 보여주기 위해 사용하는 GIF를 첨부했습니다.

여기에 이미지 설명을 입력하십시오



18
심지어 신의 정렬 알고리즘 (각 요소가 속한 위치를 알려주는 오라클에 액세스 할 수있는 가상 정렬 알고리즘)조차도 O (n)의 런타임을 갖습니다. 왜냐하면 잘못된 위치에있는 각 요소를 한 번 이상 이동해야하기 때문입니다.
Philipp

답변:


59

O (log (n))이 아니라 O (n * log (n))입니다. 정확하게 추측 했으므로 전체 입력을 반복해야하며 O (log (n)) 번 발생해야합니다 (입력은 O (log (n)) 번만 절반 만 가능). log (n) 번 반복 된 n 개의 항목은 O (n log (n))를 제공합니다.

비교 정렬이 이보다 더 빠르게 작동 할 수 없음이 입증되었습니다. 기수 정렬과 같은 입력의 특수 속성에 의존하는 정렬 만이 복잡성을 극복 할 수 있습니다. mergesort의 상수 요소는 일반적으로 그리 크지 않지만 복잡성이 더 나쁜 알고리즘은 종종 시간이 덜 걸릴 수 있습니다.


3
s / 빠름 / 더 낮은 복잡도 /
jk.

33

병합 정렬의 복잡성은 O (nlogn) 및 NOT O (logn)입니다.

병합 정렬은 나누기 및 정복 알고리즘입니다. 3 단계로 생각하십시오.

  1. 나누기 단계는 각 하위 배열의 중간 점을 계산합니다. 이 단계는 각각 O (1) 시간이 걸립니다.
  2. 정복 단계는 n / 2 개의 요소 (각 n 개)의 두 개의 하위 배열을 재귀 적으로 정렬합니다.
  3. 병합 단계는 O (n) 시간이 걸리는 n 개의 요소를 병합합니다.

이제 1 단계와 3 단계, 즉 O (1)과 O (n) 사이에서 O (n)이 더 높습니다. 1 단계와 3 단계는 총 O (n) 시간이 걸립니다. 상수에 대한 cn이라고 가정하십시오. c.

이 단계는 몇 번이나 실행됩니까?

이를 위해 아래의 트리를 살펴보십시오-각 레벨마다 위에서 아래로 각각의 레벨 2는 길이가 n / 2 인 2 개의 서브 어레이에서 merge 메소드를 호출합니다. 여기서 복잡성은 2 * (cn / 2) = cn 레벨 3 호출 길이가 각각 n / 4 인 4 개의 서브 어레이에 대한 병합 메소드입니다. 여기서 복잡성은 4 * (cn / 4) = cn 등입니다 ...

이제이 트리의 높이는 주어진 n에 대해 (로그 + 1)입니다. 따라서 전체 복잡성은 (logn + 1) * (cn)입니다. 병합 정렬 알고리즘의 경우 O (nlogn)입니다.

n 개의 요소에 대한 병합 병합

이미지 크레디트 : Khan Academy


9

병합 정렬은 재귀 알고리즘이며 시간 복잡도는 다음과 같은 반복 관계로 표현할 수 있습니다.

T (n) = 2T (n / 2) + ɵ (n)

위의 반복은 반복 트리 방법 또는 마스터 방법을 사용하여 해결할 수 있습니다. 마스터 방법의 II에 해당하고 재귀의 해가 ɵ (n log n) 인 경우에 해당합니다.

병합 정렬은 항상 배열을 두 반으로 나누고 선형 시간을 사용하여 두 반쪽을 병합하므로 병합 정렬의 시간 복잡도는 3 가지 경우 (최악, 평균 및 최고)에서 all (nLogn)입니다.

입력 배열을 두 반으로 나누고 두 반쪽을 호출 한 다음 정렬 된 두 반쪽을 병합합니다. merg () 함수는 두 개의 반쪽을 병합하는 데 사용됩니다. 병합 (arr, l, m, r)은 arr [l..m] 및 arr [m + 1..r]이 정렬되어 정렬 된 두 하위 배열을 하나로 병합한다고 가정하는 핵심 프로세스입니다. 자세한 내용은 다음 C 구현을 참조하십시오.

MergeSort(arr[], l,  r)
If r > l
     1. Find the middle point to divide the array into two halves:  
             middle m = (l+r)/2
     2. Call mergeSort for first half:   
             Call mergeSort(arr, l, m)
     3. Call mergeSort for second half:
             Call mergeSort(arr, m+1, r)
     4. Merge the two halves sorted in step 2 and 3:
             Call merge(arr, l, m, r)

여기에 이미지 설명을 입력하십시오

다이어그램을 자세히 살펴보면 크기가 1이 될 때까지 배열이 두 개 반으로 재귀 적으로 나뉘어져 있음을 알 수 있습니다. 크기가 1이되면 병합 프로세스가 작동하고 전체 배열이 될 때까지 배열 병합을 다시 시작합니다. 합병.


1
병합 부분의 특성과 이것이 O (n log n) 성능에 어떻게 기여하는지 자세히 설명해 주시겠습니까?

병합 함수의 복잡성은 O (n)입니다. 입력으로 2 개의 배열이 필요하므로 이들을 비교하고 새로운 출력을 제공합니다. 배열에서 각 요소를 다른 모든 요소와 비교할 때이 병합 함수의 복잡성은 O (n)이됩니다.
Nishant sethi

1
나는 이런 종류의 시각화를 좋아합니다!
spaaarky21

0

비교 기반 정렬 알고리즘에는 하한 𝞨(n*log(n))이 있으므로 비교 기반 정렬 알고리즘을 사용할 수 없습니다.O(log(n)) 시간이 복잡한 .

그건 그렇고, 병합 정렬은 O(n*log(n))입니다. 이런 식으로 생각하십시오.

[ a1,a2,         a3,a4,         a5,a6,          a7,a8     .... an-3,an-2,     an-1, an ] 
   \ /            \  /           \ /             \  /            \  /            \  /    
    a1'            a3'            a5'             a7'            an-3'           an-1'    
      \            /                \             /                 \             /
            a1''                          a5''                       an-3''
             \                             /                         /
                          a1'''                                     /
                           \
                                              a1''''

이진 트리가 반대로 보입니다.

입력 크기를 n .

각각 a_n은 요소 목록을 나타냅니다. 첫 번째 줄 a_n에는 하나의 요소 만 있습니다.

각 수준에서 평균 합병 비용의 합은 평균입니다 n(비용이 더 낮은 경우가 있습니다 [1]). 그리고 나무의 높이는입니다 log_2(n).

따라서 병합 정렬의 시간 복잡성은입니다 O(n*log_2(n)).

[1] 이미 정렬 된 목록에서 정렬하는 경우이를 최상의 사례라고합니다. 비용이으로 감소했습니다 n/2 + n/4 + n/8 + .... + 1 = 2^log_2(n) -1 ~ O(n). (길이 n가 2의 거듭 제곱 이라고 가정 )


-2

정렬은 컴퓨터 과학의 NP-Complete 문제입니다 (비 다항식 문제). 이것은 수학적으로 입증되지 않으면 요소 목록을 정렬 할 때 O (n log n) 아래로 갈 수 없다는 것을 의미합니다.

Wikipedia에서이 기사를 확인하십시오 ( https://en.wikipedia.org/wiki/P_versus_NP_problem )

기본적으로 지금까지 아무도 그것을 증명하지 못했습니다 (P == NP). 그렇게하면 먼저 백만장자가되고, 두 번째로 당신은 사용 된 모든 술집 / 개인 주요 보안 메커니즘을 깰 수 있기 때문에 제 3 차 세계 대전을 시작합니다. 요즘 어디서나 :)


2
NP의 의미가 아닙니다. BubbleSort도 P에 있습니다. P에 속하지 않는 정렬을 시도해야합니다 (예 : BogoSort)
Caleth
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.