두 개의 반쪽이 전체 데이터 세트를 처리하는 작업의 절반 미만을 차지하는 경우 문제를 더 빨리 해결할 수 있다는 것이 이해가됩니다.
이것이 분할 및 정복 알고리즘의 본질 이 아닙니다 . 일반적으로 요점은 알고리즘이 "전체 데이터 세트를 처리 할"수 없다는 것입니다. 대신, 두 개의 숫자 정렬과 같이 해결하기가 쉽지 않은 조각으로 나뉘고, 사소하게 해결되고 결과가 전체 데이터 세트에 대한 솔루션을 산출하는 방식으로 재결합됩니다.
그러나 데이터 세트를 세 부분으로 나누지 않는 이유는 무엇입니까? 네? 엔?
주로 두 개 이상의 부분으로 나누고 두 개 이상의 결과를 다시 결합하면 구현이 더 복잡해 지지만 알고리즘의 기본 (Big O) 특성은 변경되지 않습니다. 차이는 일정한 요소이며 속도가 느려질 수 있습니다. 둘 이상의 부분 집합을 나누고 재결합하면 추가 오버 헤드가 발생합니다.
예를 들어, 3 방향 병합 정렬을 수행하는 경우 재조합 단계에서 이제 각 요소에 대해 가장 큰 3 개의 요소를 찾아야합니다.이 경우 1 대신 2 개의 비교가 필요하므로 전체적으로 두 배의 비교가 수행됩니다. . 그 대신에 재귀 깊이를 ln (2) / ln (3) == 0.63만큼 줄이므로 스왑은 37 % 줄어들지 만 비교 (및 메모리 액세스)는 2 * 0.63 == 26 % 증가합니다. 그것이 좋은지 나쁜지는 하드웨어에서 더 비싼 것에 달려 있습니다.
또한 3-way 퀵 정렬에 대한 많은 참조를 보았습니다. 이것은 언제 더 빠릅니까?
퀵 정렬 의 이중 피벗 변형은 동일한 수의 비교가 필요하지만 평균적으로 스왑이 평균 20 % 적다는 것이 입증되어 순 이익입니다.
실제로 무엇이 사용됩니까?
요즘 누구도 더 이상 자체 정렬 알고리즘을 프로그래밍하지 않습니다. 그들은 도서관에서 제공하는 것을 사용합니다. 예를 들어, Java 7 API는 실제로 이중 피벗 퀵 정렬을 사용합니다.
어떤 이유로 든 자체 정렬 알고리즘을 실제로 프로그래밍하는 사람들은 대부분의 경우 오류 가능성이 20 % 더 뛰어 나기 때문에 간단한 2-way 변형을 고수하는 경향이 있습니다. 지금까지 가장 중요한 성능 향상은 코드가 "작동하지 않음"에서 "작동 중"으로 바뀌는 경우입니다.