정수 배열에 대한 가장 빠른 정렬 알고리즘은 무엇입니까?


55

고등학교 공부 중에 많은 정렬 알고리즘을 접했습니다. 그러나 임의의 정수 배열에 대해 가장 빠른 것이 무엇인지 결코 알 수 없습니다. 그래서 내 질문은 :

  • 현재 가장 빠른 정렬 알고리즘은 무엇입니까?
  • 이론적으로 더 빠른 것이있을 수 있습니까? 그렇다면 정렬이 가장 복잡하지 않은 것은 무엇입니까?

6
"빠른"은 무슨 뜻입니까? 무엇을 측정하고 싶습니까?
Raphael

2
"임의의 임의 배열"이란 무엇입니까? 어떤 분포에 무작위입니까? 균등 분포? 가우시안? 분포에 따라 영형(로그) 예상 실행 시간 알고리즘 보다 낫습니다 .
Bakuriu

@gen Radix 정렬을 살펴보십시오. 예를 들어 올바른 구현에는 Int32에 대한 O (n) 복잡성이 있습니다.
this


1
@gen : 무증상 측면에서 ? 그런 다음 쉽습니다. Θ ( n log n ) 알고리즘 중 하나를 선택하십시오 . 이것은 (평균) 실제 성능과 관련 이 없을 수 있습니다 . 이것은 이와 관련하여 읽을만한 가치가 있습니다. ΘΘ(nlogn)
Raphael

답변:


42

일반적 으로 삽입 정렬, 버블 정렬 및 선택 정렬과 같은 정렬 알고리즘이 있으며 일반적으로 특수한 상황에서만 사용해야합니다. Quicksort는 최악의 경우 O ( n 2 ) 이지만 상수와 속성이 양호하고 범용 정렬 절차로 사용될 수있는 O ( n log n ) 입니다. O는 ( N 로그 N ) 도 좋은 범용 정렬 알고리즘이다 병합 - 정렬 힙 정렬 알고리즘 등을; 그리고 O ( n영형(2)영형(2)영형(로그)영형(로그) 또는 기수, 버킷 및 카운팅 정렬과 같은 정수 목록에 대한 선형 정렬 알고리즘으로, 목록의 정수 특성에 따라 적합 할 수 있습니다.영형()

목록의 요소가 그 요소에 대한 전체 순서 관계 만 알고있는 경우 최적 정렬 알고리즘은 복잡도 됩니다. 이것은 매우 멋진 결과이며 온라인에서 쉽게 세부 정보를 찾을 수 있어야합니다. 선형 정렬 알고리즘은 요소 간의 전체 순서 관계가 아니라 정렬 할 요소의 구조에 대한 추가 정보를 활용합니다.Ω(로그)

더 일반적으로 정렬 알고리즘의 최적 성은 정렬하려는 목록의 종류 (알고리즘이 실행될 기계 모델뿐만 아니라 정렬이 불량한 경우도 있음)에 대해 가정 할 수있는 가정에 따라 밀접하게 결정됩니다. 알고리즘이 최선의 선택이며, 저장 용 테이프가있는 머신에서는 버블 정렬을 고려하십시오. 가정이 강할수록 알고리즘에서 더 많은 모서리를 줄일 수 있습니다. 목록의 "정렬"을 얼마나 효율적으로 결정할 수 있는지에 대한 매우 약한 가정 하에서 최적의 최악의 경우 복잡도는 있습니다.Ω(!)

이 답변은 복잡성 만 다룹니다. 알고리즘 구현의 실제 실행 시간은 단일 답변에서 설명하기 어려운 많은 요소에 따라 달라집니다.


나는 중 일부 가 Ω 이어야한다고 생각한다 . 영형Ω
Raphael

1
@Raphael Meh. 나는 그들 대부분이 어쨌든 라고 생각합니다 . 나는 하한이 아마도 Ω으로 더 잘 렌더링 될 것이라고 생각합니다 . 가장 적합한 두 가지를 변경하겠습니다. ΘΩ
Patrick87

7
나는 @Raphael가 도착 투표 경찰 모자 P :Ω
Realz 양배추

2
@RealzSlaw : 자랑스럽게 착용 할 것입니다. :]
라파엘

1
@gen 토론에 대해서는 stackoverflow.com/a/3274203 을 참조하십시오 . 기본적으로 개별 레코드가 크며 무작위 액세스 방식으로 저장되지 않고 데이터 양이 제자리에서 수행되어야하는 양이면 데이터 정렬이 진행됩니다. 이러한 상황은 오늘날 거의 드물지만 여전히 발생할 수 있습니다.
Patrick87

16

그와 같은 질문에 대한 대답은 종종 "의존"입니다. (a) 정수의 크기, (b) 입력 배열에 임의의 순서로 정수를 포함하는지 또는 거의 정렬 된 순서로 정수를 포함하는지, (c) 정렬 알고리즘이 안정적인지 여부, (d) 전체 숫자 목록이 메모리 (메모리 내 정렬 대 외부 정렬)에 맞는지 여부 및 (e) 컴퓨터를 실행하는 기계.

실제로, 메모리 내 정렬이 필요한 경우 언어 표준 라이브러리의 정렬 알고리즘이 아마도 아주 좋을 것입니다 (최적에 가깝습니다). 따라서 실제로는 표준 라이브러리에서 제공하는 정렬 기능을 사용하고 실행 시간을 측정하십시오. (i) 정렬이 전체 실행 시간의 큰 부분이고 (ii) 실행 시간이 허용되지 않는 경우에만 정렬 알고리즘을 어지럽히 지 않아도됩니다. 이 두 조건 충족되면 특정 도메인의 특정 측면을보고 다른 빠른 정렬 알고리즘을 실험 할 수 있습니다.

그러나 현실적으로 정렬 알고리즘은 거의 큰 성능 병목 현상이 아닙니다.


9

또한 두 번째 질문에 대답

이론적으로는 더 빠른 것이 가능합니까?
그렇다면 정렬이 가장 복잡하지 않은 것은 무엇입니까?

범용 정렬의 경우 비교 기반 정렬 문제 복잡도는 Ω (n log n) 입니다. O (n)에서 정렬을 수행하는 알고리즘이 있지만 모두 입력에 대한 가정을 기반으로하며 범용 정렬 알고리즘이 아닙니다.

기본적으로 배열을 정렬하는 데 필요한 최소 비교 수에 의해 복잡성이 부여됩니다 (log n은 배열의 각 요소를 비교할 때 작성된 이진 결정 트리의 최대 높이를 나타냄).

정렬 복잡성에 대한 공식적인 증거는 여기에서 찾을 수 있습니다 .


3
이 답변은 옳지 않습니다. 은 정렬을위한 범용 하한값이 아닙니다. 이 하한은 비교 기반 정렬, 즉 비교 만 사용하는 정렬 알고리즘 에만 적용됩니다 . 일부 정렬 알고리즘은 비교 기반이 아닙니다. "O (n)에서 정렬을 수행하는 알고리즘이 있지만 모두 입력에 대한 가정에 의존하며 범용 정렬 알고리즘이 아닙니다." 약간 오해의 소지가 있으므로 조심하십시오. 기수 정렬은 범용 정렬 알고리즘입니다 (고정 너비 정수를 정렬한다고 가정). Ω(로그)
DW

정렬 문제의 의미에 따라 다릅니다 . 범용 비교 기반 정렬은 사람들이 갖는 유일한 정렬 문제가 아닙니다.
Patrick87

1
물론 그렇습니다. 지적 해 주셔서 감사합니다. 그러나 나는 당신이 언급하고있는 다른 정렬 방법 (비교 기반이 아닌)에 대해 약간 궁금했습니다. 기수 정렬은 정확히 내가 말한 O (n) 알고리즘의 일종입니다. 입력에 대해 무언가를 '고정 너비 정수'로 가정해야합니다. 이런 의미에서, 그것은 범용 정렬 알고리즘이 아닙니다.
rla4

1
@DW : 기수 정렬은 고정 길이 정수 키가 필요하기 때문에 '일반적인 목적'정렬 알고리즘으로 간주되어서는 안됩니다. 그렇지 않으면 유용하지 않습니다. 그러나 나는 당신의 요점을 얻는다. :) 내 실수는 특히 정수 를 정렬하는 대신 비교할 수있는 정렬에 중점을 둔 것으로 생각 합니다. 그것들은 다른 문제이며 가능한 해결책 세트가 다릅니다. 이 질문에는 "임의의 정수 배열"이 언급되어 있지만 제한이 아니라 예제로 사용했습니다.
rla4

2
@DavidRicherby, 1 년 반 후에 이것을 되돌아 보면, 나는 당신에 동의합니다. 감사합니다.
DW

3

내가 본 최악의 경우에 가장 빠른 정수 정렬 알고리즘은 Andersson et al. 최악의 경우 이며, 물론 O ( n log n ) 보다 빠릅니다 .영형(로그로그)영형(로그)


2
매우 흥미롭지 만 더 많은 정보를 제공해야합니다. 을 언급 했으므로 일반 정수의 비교 기반 정렬에는 시간 Ω ( n log n )이 필요하다는 것을 알고 있다고 가정합니다 . 예를 들어 기수 정렬은 배열의 모든 요소가 거의 일정하다고 가정하고 선형 시간으로 실행됩니다. 이 알고리즘은 어떤 조건 하에서 O ( n log log n ) 로 분류되며 퀵 정렬 및 기수 정렬과 같은 다른 알고리즘에 대해 실제로 어떻게 수행됩니까? 로그Ω(로그)영형(로그로그)
David Richerby

1

이 글을 쓸 당시 다른 두 가지 답변을 읽었으며 어느 쪽이 귀하의 질문에 적절하게 대답하지 않았다고 생각합니다. 다른 답변은 임의 분포와 공간 복잡성에 관한 외래의 아이디어를 고려했는데, 이는 아마도 고등학교 연구 범위를 벗어난 것입니다. 그래서 여기에 내 테이크가 있습니다.

정수 요소 가 n 인 배열 가 주어지면 A 가 정렬 되어 있는지 확인하기 위해 요소 사이를 정확히 ( n - 1 ) 비교 해야합니다 ( 배열의 시작 부분에서 시작하여 마지막 요소와 비교하여 다음 요소를 확인하십시오). 실제로 ( n - 1 ) 비교는 정렬 알고리즘에 가장 적합한 실행 시간입니다 . 즉, 정렬 알고리즘의 실행 시간 하한은 Ω ( n ) 입니다. 기수 정렬 또는 버킷 정렬을 리콜하면 실행 시간이 O ( n에이(1)에이(1)Ω() . 모든 정렬 알고리즘이 Ω ( n ) 아래로 묶여 있기 때문에기수 정렬과 버킷 정렬이 정수 배열을 정렬하는 가장 빠른 알고리즘이라고 주장합니다.영형()Ω()

또한 또는 O ( n )에 익숙하지 않은 경우 : 두 표기법 모두 알고리즘 을 완료하는 데 대략 n 개의 작업 이 필요하다는 것을 의미합니다 ( 2 n 또는 3 n - 5 일 수 있지만 1 또는 n 2 작업은 아님). .Ω()영형()2512


네,하지만 시간을 실행하는 것도 어떻게 든 거의 앞에있는 일정하기 때문에, 부정 행위입니다 N 효과적으로 확장 같은 LG N을 (32 비트 시스템 모델을 가정하고 있기 때문에, 그리고이 의미하는 N 2 32 ) . 따라서 O ( n ) (기수 정렬 용) O ( n lg n ) 보다 훨씬 나아 보이지만O(n)lg232영형()영형(lg)(quicksort 또는 mergesort의 경우) 실제로 비교는 명확하지 않습니다 .big-O 표기법에 숨겨진 상수가 매우 중요 해지고 기수 정렬의 상수가 quicksort 또는 mergesort의 상수보다 높습니다.
DW

"n 앞에있는 상수는 처럼 효과적으로 확장됩니다. "나는 실제로이 구의 의미를 이해하지 못합니다 (Big-Oh 표기법은 작은 n에 중요 할 수있는 상수를 숨기고 있음을 이해합니다 ). ()
bourbaki4481472

나는 그것이 아래쪽에 결합 말을 아마 잘못된 생각 어떤 정렬 알고리즘 것은 . 그보다 훨씬 빠르게 정렬 할 수있는 가정을 인정하는 자연적인 문제가 충분히있을 수 있습니다. 더 빠른 알고리즘을 가진 학술적으로 논의 할 수있는 정렬 문제가 있습니다. 물론, 그 시점에서 우리는 실제로 "정렬"이 무엇인지, 문제의 크기가 무엇인지에 대해 토론하고있을 수 있지만 그 요점은 여전히 ​​남아 있습니다. Ω()
Patrick87

2
@DW의 요점은 기수 정렬의 실제 비용은 이며 여기서 w 는 단어 길이입니다. 상수 w 를 고정하면영형() 비트로 기록 할 수있는 정렬 숫자 만 (즉, { 0 , , 2 w - 1 } ) 정렬하면 선형 시간으로 정렬 할 수 있습니다. 그러나 당신이 당신의 수에 상한을 해결하지 않으면, 그것은 정도 걸립니다 로그 n 개의 당신의 쓰기 비트 n 개의 숫자를, 그래서 w = 로그 N 과 기수 정렬은 시간에 실행되고있는 N 로그 N을{0,,21}로그=로그로그.
David Richerby

1

정수 정렬의 경우 가장 잘 알려진 결과는 다음과 같습니다. 무작위 알고리즘 (또는O(n )을 사용하여 기대하는 l o g l o g n )

영형(영형영형)
상한 주어진 경우U를통해)한, Thorup.영형(영형영형)


0

하드웨어에 대한 제한을 언급하지 않고 "가장 빠른"제품을 찾고 있다면 사용 가능한 하드웨어와 입력 종류에 따라 병렬 정렬 알고리즘 중 하나를 선택해야한다고합니다.

이론적으로 예를 들면 quick_sort이다 O(n log n). p프로세서를 사용하면 O(n/p log n)병렬로 실행하는 것이 이상적 입니다.

위키 백과를 인용하려면 : 시간 복잡성 ...

최적의 병렬 정렬은 O (log n)입니다.

실제로 대규모 입력 크기의 경우 O(log n)확장 성 문제로 인해 달성하기가 불가능 합니다.

다음은 병렬 병합 정렬에 대한 의사 코드입니다 . 구현은 merge()일반 병합 정렬과 동일 할 수 있습니다.

// Sort elements lo through hi (exclusive) of array A.
algorithm mergesort(A, lo, hi) is
    if lo+1 < hi then  // Two or more elements.
        mid = ⌊(lo + hi) / 2⌋
        fork mergesort(A, lo, mid)
        mergesort(A, mid, hi)
        join
        merge(A, lo, mid, hi)

참조 :


Quicksort는 표준 형식의 병렬 처리에 실제로 적합하지 않습니다. 즉, 모든 bitonic sorter가 더 우수해야하거나 Quicksort가 수정되거나 (병합 단계가 지배적 인 인트로 정렬보다) 여러 분할 단계가 수행됨을 의미합니다. 호스트 환경에서 병렬 처리를 위해 비생산적입니다. 이론적으로 Quicksort는 실제로 입니다.영형(2)
Evil

@ 이블 예. Quicksort는 병렬 처리에 적합하지 않습니다. 예입니다. 사용해야하는 것이 주어진 링크에 나열되어 있습니다.
Kashyap
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.