각 정렬 알고리즘은 언제 사용됩니까? [닫은]


170

특정 정렬 알고리즘이 다른 정렬 알고리즘보다 선호되는 사용 사례는 무엇입니까-병합 정렬 대 QuickSort 대 힙 정렬 대 '인트로 정렬'등?

크기, 데이터 구조 유형, 사용 가능한 메모리 및 캐시 및 CPU 성능에 따라 사용하는 데 권장되는 안내서가 있습니까?


다양한 종류의 데이터 및 알고리즘에 대한 애니메이션 세트는 <a href=" sorting-algorithms.com/"> sorting-algorithms.com </ a > 에서 찾을 수 있습니다.
Chip Uni

2
같은 가이드 bigocheatsheet.com 이 물건은 greaaaat 것
K - SO의 독성이 증가하고있다.

@ChipUni는 고정 된 링크입니다 : toptal.com/developers/sorting-algorithms
eric

2
이 질문이 왜 닫힙니 까!?
Arvand

답변:


316

첫째, 정의는 매우 중요하기 때문에 정의입니다. 안정적인 정렬 은 동일한 키로 요소를 재정렬하지 않도록 보장하는 것입니다.

추천 :

빠른 정렬 : 안정적인 정렬이 필요하지 않고 평균 사례 성능이 최악의 경우보다 중요합니다. 빠른 정렬은 평균 O (N log N), 최악의 경우 O (N ^ 2)입니다. 좋은 구현은 재귀를 위해 스택 공간 형태로 O (log N) 보조 기억 장치를 사용합니다.

정렬 정렬 : 안정적인 O (N log N) 정렬이 필요한 경우 이것이 유일한 옵션입니다. 그것의 유일한 단점은 O (N) 보조 공간을 사용하고 빠른 정렬보다 약간 큰 상수를 가지고 있다는 것입니다. 적절한 병합 정렬이 있지만 AFAIK는 모두 O (N log N)보다 안정적이거나 나쁘지 않습니다. 제자리에있는 O (N log N)조차도 평범한 기존 병합 정렬보다 상수가 훨씬 커서 유용한 알고리즘보다 이론적 호기심이 많습니다.

힙 정렬 : 안정적인 정렬이 필요하지 않고 평균 케이스 성능보다 최악의 케이스 성능에 더 관심이있는 경우. O (N log N)이어야하며 O (1) 보조 공간을 사용하므로 매우 큰 입력에서 예기치 않게 힙 또는 스택 공간이 부족하지 않습니다.

Introsort : 빠른 정렬의 O (N ^ 2) 최악의 경우를 피하기 위해 특정 재귀 깊이 후에 힙 정렬로 전환되는 빠른 정렬입니다. O (N log N) 성능을 보장하면서 빠른 정렬의 평균 사례를 얻으므로 거의 항상 일반 오래된 빠른 정렬보다 낫습니다. 아마도 이것 대신 힙 정렬을 사용하는 유일한 이유는 O (log N) 스택 공간이 실질적으로 중요한 메모리 제한 시스템에 있기 때문입니다.

삽입 정렬 : 빠른 정렬 또는 병합 정렬의 기본 사례를 포함하여 N이 작을 때. 이것은 O (N ^ 2)이지만 상수는 매우 작으며 안정적인 정렬입니다.

Bubble sort, selection sort : 빠르고 더러운 일을 할 때 어떤 이유로 든 표준 라이브러리의 정렬 알고리즘을 사용할 수 없습니다. 삽입 정렬에 비해 이러한 장점은 구현하기가 조금 더 쉽다는 것입니다.


비 비교 정렬 : 상당히 제한된 조건에서는 O (N log N) 장벽을 깨고 O (N)으로 정렬 할 수 있습니다. 시도해 볼 가치가있는 경우는 다음과 같습니다.

계수 정렬 : 범위가 제한된 정수를 정렬 할 때.

기수 정렬 : log (N)이 K보다 상당히 큰 경우 K는 기수의 수입니다.

버킷 정렬 : 입력이 대략 균일하게 분산 될 수 있습니다.


1
내가 기억 하듯이 힙 정렬은 동일한 크기의 다른 입력간에 변동이 거의 없기 때문에 예측 가능한 실행 시간을 갖지만 일정한 공간 제한보다 관심이 적습니다. 또한 삽입 정렬이 n ^ 2 정렬을 구현하는 것이 가장 쉬운 것을 알지만 어쩌면 그것은 저뿐입니다. 마지막으로 삽입 정렬만큼 구현하기가 간단하지만 n log n은 아니지만 더 나은 성능을 갖는 Shell 정렬을 언급 할 수도 있습니다.
JaakkoK 2009

29
Bogosort를 잊지 마십시오 ! ;-)
Alex Brasetvik 2009

2
+1 매우 흥미 롭습니다. "보증 ... 대략 균일하게 분배"할 수있는 방법을 설명하고 싶습니까? 버킷 정렬
Sam Overton

2
소개가 빠른 정렬보다 실질적으로 느린 이유는 무엇입니까? 유일한 오버 헤드는 재귀 깊이를 계산하는 것이므로 무시해도됩니다. 재귀가 좋은 빠른 정렬 경우보다 훨씬 더 깊은 후에 만 ​​전환됩니다.
dsimcha 2009

2
버블 정렬의 가장 좋은 경우는 O (n)입니다.
타라

33

Quicksort 는 일반적으로 평균 속도가 가장 빠르지 만 최악의 최악의 동작이 있습니다. 따라서 나쁜 데이터를 제공하지 않으면 O(N^2)이를 피해야합니다.

병합 정렬 은 추가 메모리를 사용하지만 특히 외부 정렬 (예 : 메모리에 맞지 않는 대용량 파일)에 적합합니다.

힙 정렬 은 제자리에서 정렬 할 수 있으며 최악의 2 차 동작은 없지만 대부분의 경우 평균은 빠른 정렬보다 느립니다.

제한된 범위의 정수만 관련되는 경우 일종의 기수 정렬을 사용하여 매우 빠르게 만들 수 있습니다.

99 %의 경우, 일반적으로 퀵 정렬을 기반으로하는 라이브러리 정렬에 적합합니다.


6
+1 : "99 %의 경우 보통 퀵 정렬을 기반으로하는 라이브러리 정렬에 문제가 없습니다".
Jim G.

무작위 피벗은 Quicksort에 잘못된 데이터에 대한 보장없이 모든 실제적인 목적으로 O (nlogn)의 런타임을 제공합니다. 나는 누군가가 어떤 생산 코드에 대해 O (n ^ 2) 퀵 정렬을 구현한다고 생각하지 않습니다.
MAK

2
MAK, 예를 들어 C 표준 라이브러리 qsort? ( google.com/codesearch/… ) – 대부분의 "제작 코드"에 의존하는
Eli Bendersky

라이브러리 정렬은 안정적이지 않기 때문에 일반적으로 퀵 정렬을 기반으로하지 않습니다. 거의 모든 고급 언어 (C에 대한 기대)는 안정적인 정렬을 제공합니다. 대부분의 경우 나는 당신이 안정적이고 적어도 결정 론적 인 정렬이 필요하다는 것을 알고 있습니다.
12431234123412341234123


3

제공된 비교 / 애니메이션에 대한 링크가 고려하지 않는 것은 데이터 양이 사용 가능한 메모리를 초과 할 때입니다. 이 작업을 수행해야하는 경우 일반적으로 병합 및 힙 정렬의 변형을 다루는 "외부 정렬"을 읽으십시오.

http://corte.si/posts/code/visualisingsorting/index.htmlhttp://corte.si/posts/code/timsort/index.html 에는 다양한 정렬 알고리즘을 비교 한 멋진 이미지가 있습니다.


0

@ dsimcha 쓴 : 계산 정렬 : 제한된 범위의 정수를 정렬 할 때

나는 그것을 다음과 같이 바꿀 것입니다 :

계수 정렬 : 양의 정수를 정렬 할 때 (비둘기 구멍으로 인해 0-정수. MAX_VALUE-2).

선형 시간에서 효율성 휴리스틱으로 최대 및 최소 값을 항상 얻을 수 있습니다.
또한 중간 배열에는 최소 n 개의 추가 공간이 필요하며 안정적입니다.

/**
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

(실제로 MAX_VALUE-2까지 허용하지만) 참조 : Java 배열의 최대 크기는?

또한 기수 정렬 복잡도가 단어 크기 w의 정수인 n 키에 대해 O (wn)라고 설명합니다. 때때로 w는 상수로 표시되는데, 이는 n을 정렬하기 위해 O (n log n) 비교를 수행하는 최상의 비교 기반 정렬 알고리즘보다 기수 정렬을 더 좋게 (충분히 큰 n) 만들 수있게합니다. 그러나 일반적으로 w는 상수로 간주 될 수 없습니다. 모든 n 키가 고유 한 경우 임의 액세스 시스템이 메모리에 키를 저장할 수 있으려면 w가 최소한 log n이어야하므로 시간이 가장 복잡합니다. (n log n). (wikipedia에서)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.