자바가 왜 원시에 기수 정렬을 사용하지 않습니까?


12

java.util.Arrays.sort(/* int[], char[], short[], byte[], boolean[] */) 는 기수 정렬이 아닌 '조정 된 빠른 정렬'로 구현됩니다.

나는 얼마 전에 속도를 비교했고 n> 10000과 같은 것으로 기수 정렬이 항상 빨랐습니다. 왜?

답변:


17

나는 그것을 추측 할 것이다 :

  • Array.sort는 quicksort로 구현됩니다. quicksort는 비교기에서 적절한 시간 안에 모든 것을 정렬 할 수 있기 때문입니다.
  • 10000 개의 항목을 정렬하는 것은 그리 일반적이지 않습니다. 10000 개 이상의 요소로 구성된 데이터 구조에 액세스하는 것이 일반적입니다. 순서를 유지해야하는 경우 가장 작은 요소가 필요할 때마다 전체 배열을 정렬하는 것보다 균형 잡힌 검색 트리를 사용하는 것이 좋습니다.
  • 대학이 가르치는 내용에도 불구하고 기본 정렬은 그리 일반적이지 않습니다.

요점은 일반적인 사용 사례는 아니며 최적화가 표준 라이브러리에 있어야한다는 것입니다. 성능 문제가있는 응용 프로그램을 작성한 경우 10000 + int의 배열을 정렬하는 것이 실제로 병목 현상인지 프로파일 링을 통해 결정하면 처음으로 정렬을 작성하거나 선택한 데이터 구조를 다시 고려할 수 있습니다 장소.


100 % 확실하지는 않지만, 현재 TimSort가 사용되는 것 같습니다.
Martijn Verburg

1
그러나 Array.sort와 같은 것은 없으며 여러 Array.sort가 있으며 질문은 숫자 유형에 특화된 것입니다.
Danubian Sailor

6

Back2dos는 모든 것을 말했지만, 내가 가장 중요하다고 생각하는 요점을 더 명확히하기 위해 노력할 것입니다.

기수 정렬은 이진 숫자 패턴을 기준으로 배열 내에 포함 된 실제 기본 값만 정렬 할 수 있습니다. 실제 소프트웨어 엔지니어링 시나리오에서는이 사례가 거의 발생 하지 않습니다 . 우리가 훨씬 더 자주하는 일은 더 복잡한 (기본이 아닌) 데이터 구조의 배열을 정렬하는 것이고, 때로는 인덱스 배열을 다른 엔티티로 정렬하는 것입니다.

이제 다른 엔티티에 대한 인덱스 배열은 실제로 프리미티브의 배열이지만 정렬 순서는 인덱스가 아니라 인덱스에 의해 인덱스 된 엔티티를 비교하는 비교기 인터페이스 (및 / 또는 C #의 대리자)에 의해 제공됩니다. 따라서 정렬 순서는 프리미티브 값의 순서와 전혀 관련이 없으므로 기수 정렬은이 시나리오에서 절대 쓸모가 없습니다.

예를 들면 :

[0] = "Mike", [1] = "Albert", [2] = "Zoro"라는 문자열 배열이 있습니다. 그런 다음 [0] = 0, [1] = 1, [2] = 2 문자열에 인덱스 배열을 선언합니다. 그런 다음 인덱스 배열을 정렬하여 인덱스 자체가 아니라 이러한 인덱스가 참조하는 실제 문자열을 비교하는 비교기를 전달합니다. 정렬 후 결과 인덱스 배열은 다음과 같습니다 : [0] = 1, [1] = 0, [2] = 2. 보시다시피,이 정렬 순서는 배열에 포함 된 값의 이진 패턴과 아무 관련이 없지만이 인덱스 배열을 순회하고 각 해당 문자열을 가져 와서 정렬 된 순서로 문자열을 방문합니다.

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