이 정렬 알고리즘은 최악의 경우 Θ (n²)가 아닌 Θ (n³)는 어떻습니까?


52

방금 데이터 구조 및 알고리즘에 대한 강의를 시작했으며 교수 조교는 정수 배열을 정렬하기 위해 다음과 같은 의사 코드를 제공했습니다.

void F3() {
    for (int i = 1; i < n; i++) {
        if (A[i-1] > A[i]) {
            swap(i-1, i)
            i = 0
        }
    }
}

명확하지 않을 수도 있지만 여기서 nA정렬하려는 배열의 크기입니다 .

어쨌든, 교육 보조원은이 알고리즘이 Θ(n3) 시간 (최악의 경우, 믿습니다)이라고 수업에 설명 했지만, 여러 번 정렬 된 배열로 처리하는 횟수에 관계없이 나에게 그것은 이어야 Θ(n2)하고 이어야합니다 Θ(n3).

왜 이것이 아닌 인지 설명해 줄 수 있습니까?Θ(n3)Θ(n2)


분석 에 대한 구조화 된 접근 방식에 관심이있을 수 있습니다 . 스스로 증거를 찾아보십시오!
Raphael

그것을 구현하고 자신을 설득하기 위해 측정하십시오. 10,000 개의 요소가 역순으로 배열 된 경우 몇 분이 걸리고 20,000 개의 요소가 역순으로 배열 된 경우 약 8 배 더 오래 걸립니다.
gnasher729

@ gnasher729 당신은 틀리지 않지만 내 해결책은 다릅니다 : 당신이 바운드 를 증명 하려고 시도 하면 끊임없이 실패 할 것입니다. (물론, 둘 다 할 수 있습니다. 플로팅 / 피팅은 가설을 기각하는 데 확실히 빠르지 만 신뢰성은 떨어 집니다. 공식 / 구조적 분석을 위해 어떤 종류의 행동을하는 한 해가되지 않습니다. 플롯에 의존 하는 것이 문제가 시작되는 곳입니다.)O(n2)
라파엘

1
때문에의 i = 0
njzk2

답변:


61

이 알고리즘은 다음과 같이 다시 작성할 수 있습니다

  1. 반전A 을 찾을 때까지 스캔하십시오 .
  2. 하나를 찾으면 바꾸고 다시 시작하십시오.
  3. 없는 경우 종료하십시오.

이제 최대 반전이있을 수 있으며 각각을 찾으려면 선형 시간 스캔이 필요합니다. 따라서 최악의 실행 시간은 . 그것은 많은 성공에 패턴 일치 접근을 트립으로 아름다운 교수 예!(n2)Θ(n2)Θ(n3)

참고 사항 : 약간 조심해야합니다. 일부 반전은 초기에, 늦게 나타나기 때문에 비용이 청구 된대로 (하한값에 대해) 추가되는 것은 그리 쉬운 일이 아닙니다. 또한 스왑이 새로운 반전을 일으키지 않음을 관찰해야합니다 . 역으로 정렬 된 배열의 경우에 대한 자세한 분석은 가우스 공식의 2 차 경우와 같은 결과를 낳습니다.

@ gnasher729는 적절하게 언급했듯이 입력을 정렬 할 때 실행 시간을 분석 하여 최악의 실행 시간이 임을 쉽게 알 수 있습니다 (이 입력 아마도 아니지만 최악의 경우).Ω(n3)[1,2,,n,2n,2n1,,n+1]

주의 : 거꾸로 정렬 된 배열이 모든 정렬 알고리즘에 대해 최악의 경우 입력이라고 가정하지 마십시오. 알고리즘에 따라 다릅니다. 역 정렬 된 배열이 최악의 경우가 아니며 최상의 경우에 가까운 정렬 알고리즘이 있습니다.


14
첫 번째 절반이 오름차순으로 숫자 1에서 n / 2로 구성되고 두 번째 반이 역순으로 n에서 n / 2 + 1 인 배열을 취하면 적어도 n / 2가 필요하다는 것이 분명합니다. 각 반전을 찾는 단계가 있으며 그 중 약 (n / 2) ^ 2 / 2가 있습니다. 그리고 그것은 최악의 경우가 아닙니다.
gnasher729

@AnthonyRossello 표준 결과입니다 (순열 조합으로). 간단히 말해서, 반대로 정렬 된 배열의 반전 수를 세십시오 (최악의 경우임이 분명합니까?). 가우스 합계입니다.
Raphael

의 부분 합 은 항상 이므로 빠르게 떨어지는 계수 일 뿐이라는 것을 기억해야합니다. (매우 큰 계수 ). 문제는 는 계수에 관심이 없습니다. Θ(nα)Θ(nα+1)k=0nkα1α+1nα+11α+1Θ
yo '

2
@yo '그리고 이것은 답변 (또는 질문)과 어떻게 관련이 있습니까?
Raphael

7

이에 대해 생각하는 다른 방법 i은 재설정되기 전에 최대 값이 되는 것입니다. 결과적으로 이전 정렬 순서가 A알고리즘의 런타임 에 어떤 영향 을 미치는지 에 대한 이유를보다 쉽게 ​​알 수 있습니다 .

특히 i새로운 최대 값을 설정하고 N이라고하면 배열 [A[0], ..., A[N-1]]이 오름차순으로 정렬됩니다.

그러면 요소 A[N]를 믹스에 추가하면 어떻게됩니까 ?

수학 :

자, 그것이 위치에 맞는다고 . 그럼 우리가 필요 (나는 나타내는 것이다 루프 반복 ) 장소로 이동하는 , 장소로 이동하기 위해 반복 , 및 일반적으로를 :pNNstepsN1N+(N1)N2

stepsN(pN)=N+(N1)+(N2)++(pN+1)=12(N(N+1)pN(pN+1))

무작위로 정렬 된 배열의 경우 은 다음 과 같이 각 에 대해 에 균일 분포를 취합니다 .pN{0,1,,N}N

E(stepsN(pN))=a=1NP(pN=a)stepsN(a)=a=1N1N12(N(N+1)a(a+1))=12(N(N+1)13(N+1)(N+2))=13(N21)=Θ(N2)

합계는 Faulhaber의 공식 또는 하단의 Wolfram Alpha 링크를 사용하여 표시 할 수 있습니다.

반대로 정렬 된 배열의 경우 모든 대해 이고 다음과 같이 나타납니다.pN=0N

stepsN(pN)=12N(N+1)

정확히 다른 값보다 더 오래 .pN

이미 정렬 된 배열의 경우 및 이며 하위 항은 관련성이 있습니다.pN=NstepsN(pN)=0

총 시간:

총 시간을 얻기 위해 모든 대한 단계를 요약합니다 . (우리가 매우 조심 스러우면 스왑과 루프 반복을 요약하고 시작 및 종료 조건을 처리하지만 대부분의 경우 복잡성에 기여하지 않는 것을 쉽게 알 수 있습니다) .N

그리고 다시 기대의 선형성과 Faulhaber의 공식을 사용하십시오.

Expected Total Steps=E(N=1nstepsN(pN))=N=1nE(stepsN(pN))=Θ(n3)

물론 어떤 이유로 이 가 아닌 경우 (예 : 우리 있는 배열의 분포가 이미 정렬되어있는 것에 매우 가깝습니다), 항상 그런 것은 아닙니다 사실이다. 그러나 이것을 달성하려면 에 매우 구체적인 분포가 합니다!stepsN(pN)Θ(N2)pN

관련 독서 :


@Raphael-제안 된 개선 사항에 감사드립니다. 조금 더 자세히 설명했습니다. 따라서 임의의 변수는 ( , 순서의 집합 )이므로 기대치는 기술적으로 이상입니다.piΩAΩ
David E

다른 ; 나는 Landau 하나를 의미했다. Ω
Raphael

3

기권:

이것은 증거가 아닙니다 (일부 사람들은 마치 마치 마치 마치 마치 게시 한 것으로 생각하는 것 같습니다). 이것은 OP가 과제에 대한 의심을 해결하기 위해 수행 할 수있는 작은 실험 일뿐입니다.

몇 번이나 거꾸로 정렬 된 배열로 처리하더라도 아닌 이어야합니다 .Θ(n2)Θ(n3)

이러한 간단한 코드를 사용하면 와 를 파악하기가 어렵지 않으며 많은 실제 사례에서 이는 틈새를 확인하거나 기대치를 조정하는 유용한 방법입니다.Θ(n2)Θ(n3)


@Raphael은 이미 귀하의 질문에 대답했지만 이 gnuplot 스크립트를 사용 하여이 프로그램의 출력을 맞추기 위해 발 차기 및 의 지수 값을보고 하고 다음 플롯을 생성했습니다 ( 첫 번째는 정규 스케일이고 두 번째는 로그 로그 스케일입니다.f(x)=axb+cx2.997961668332222.99223727692339

표준 로그 로그

이것이 도움이되기를 바랍니다.¨


2
모든 기능을이 값에 맞출 수 있습니다. 여기도 참조 하십시오 .
Raphael

3
@Raphael이 방법으로 nitpick하지 않으려면 아니오, 어떤 함수도 맞출 수 없습니다 (예를 들어 일정한 함수를 합리적인 정확도에 맞출 수 없음). 이것은 증거는 아니지만 스케치를 제공하는 답변이 이미 있습니다. 유용성에 대해서는 다음과 같이 링크 한 자신의 게시물을 인용 할 수 있습니다. "이 방법은 때때로 사용되지 않는 매우 유용한 방법이라는 데 동의해야합니다." 또한 OP는 보다 이어야한다고 생각 했으므로 실험을하지 않고 자신의 직감이 올바른지 확인하지 않겠습니까? 계속 Θ(n2)Θ(n3)
dtldarek

2
이것은 알고리즘이 이라는 증거를 제공 하지만 질문은 이유를 묻습니다 . 현상에 대한 설명이 아니라 확인을 요구하는 것입니다. Θ(n3)
David Richerby

2
@DavidRicherby 이것은이 답변이 유용하지 않다는 것을 의미합니까?
dtldarek

3
@Magicsowon 포럼이 아니라 질문과 답변 사이트입니다. 우리는 그 문제에 대한 토론이 아니라 질문에 대한 답을 찾고 있습니다.
David Richerby

3

배열이 있다고 가정하십시오.

array a[10] = {10,8,9,6,7,4,5,2,3,0,1}

알고리즘은 다음을 수행합니다.

Scan(1) - Swap (10,8) => {8,10,9,6,7,4,5,2,3,0,1}  //keep looking at "10"
Scan(2) - Swap (10,9) => {8,9,10,6,7,4,5,2,3,0,1}
...
Scan(10) - Swap(10,1) => {8,9,6,7,4,5,2,3,0,1,10}

기본적으로 그것은 배열의 끝으로 가장 높은 요소를 이동시키고, 그렇게함으로써 각 스캔에서 효과적으로 시작 O(n^2)합니다. 그러나 n 개의 요소 가 있으므로이 n시간 을 반복해야합니다 . 이것은 공식적인 증거는 아니지만, "비공식적 인"방식으로 달리는 시간이 왜인지 이해하는 데 도움이 O(n^3)됩니다.


4
이것은 다른 답변보다 무엇을 추가합니까? 알고리즘의 기능에 대한 설명은 이미 제공되었으며 런타임에 대한 추론은 최선의 스케치입니다. (가장 최악의 경우는 선형 적으로 행동 하지 않습니다 !)
Raphael

2
때로는 질문을하는 사람이 새로운 분야에있을 때 같은 형식으로 여러 가지 방법으로 형식적인 방식으로 설명하는 것이 가치있는 경우가 있습니다. 그래서 이것이 추가하는 것은 직관을 도울 수있는 방식으로 제시되었다는 것입니다.
DW

내 의견에 깃발로 답장을 보냈으므로 (그렇게하지 마십시오!) : "가장 최악의 사례는 선형 적으로 행동하지 않습니다!" -최악의 연산자의 대수적 속성을 의미합니다. 대략, WorstCase (1 + ... + n) "="WorstCase (1) + ... + WorstCase (n)을 사용하고 있지만이 ID는 유지되지 않습니다.
Raphael

1
나는이 분야를 처음 접했고, 구체적이고 철자 된 예제를 통해 설명을 제공함으로써 문제에 대한 직관을 얻는 데 확실히 도움이되었습니다. 이제 수용 된 솔루션이 더 이해가됩니다.
vaer-k

0

논리는 배열의 요소를 오름차순으로 정렬하는 것 같습니다.

가장 작은 숫자가 배열의 끝에 있다고 가정합니다 (a [n]). 그것이 올바른 장소에 오려면-(n + (n-1) + (n-2) + ... 3 + 2 + 1) 작업이 필요합니다. = O (n2).

배열의 단일 요소에는 O (n2) ops가 필요합니다. 따라서 건설에 대해서는 O (n3)입니다.


5
이것은 다른 답변보다 무엇을 추가합니까? 알고리즘의 기능에 대한 설명은 이미 제공되었으며 런타임에 대한 추론은 최선의 스케치입니다. (가장 최악의 경우는 선형 적으로 행동 하지 않습니다 !)
Raphael

좋은 설명입니다. 이것은 다른 답변에서는 설명하지 않고 문제에 대한보다 직관적이고 다른 관점을 제공합니다. (매우 짧고 이해하기 쉬운 것은 말할 것도 없습니다.)
2501

1
@ 2501 아니요, 잘못되었습니다. Dijkstra의 알고리즘에서이 "직관"을 사용 해보면 2 차 런타임 (노드 수)이 표시됩니다.
Raphael

@Raphael 아니요, 대답에서 설명한대로 맞습니다. 이 설명은 다른 알고리즘이 아닌이 알고리즘에 적용됩니다. 그들에게는 틀릴 수도 있지만,이 주장은 이것이 틀렸다는 것을 증명하지는 않습니다.
2501

@Raphael 나는 대답의 설명을 이해하지 못했습니다. 그래서 나는 이것을 해결하고 기술적 용어없이 간단한 용어로 설명하려고 노력했다. 그래서, 이것은 받아 들인 대답을 이해할 수없는 나와 같은 회원들을위한 것입니다. 누군가가 이것이 유용하다는 것을 알게되어 기쁩니다.
mk ..
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.