고등학교 공부 중에 많은 정렬 알고리즘을 접했습니다. 그러나 임의의 정수 배열에 대해 가장 빠른 것이 무엇인지 결코 알 수 없습니다. 그래서 내 질문은 :
- 현재 가장 빠른 정렬 알고리즘은 무엇입니까?
- 이론적으로 더 빠른 것이있을 수 있습니까? 그렇다면 정렬이 가장 복잡하지 않은 것은 무엇입니까?
고등학교 공부 중에 많은 정렬 알고리즘을 접했습니다. 그러나 임의의 정수 배열에 대해 가장 빠른 것이 무엇인지 결코 알 수 없습니다. 그래서 내 질문은 :
답변:
일반적 으로 삽입 정렬, 버블 정렬 및 선택 정렬과 같은 정렬 알고리즘이 있으며 일반적으로 특수한 상황에서만 사용해야합니다. Quicksort는 최악의 경우 O ( n 2 ) 이지만 상수와 속성이 양호하고 범용 정렬 절차로 사용될 수있는 O ( n log n ) 입니다. O는 ( N 로그 N ) 도 좋은 범용 정렬 알고리즘이다 병합 - 정렬 힙 정렬 알고리즘 등을; 그리고 O ( n 또는 기수, 버킷 및 카운팅 정렬과 같은 정수 목록에 대한 선형 정렬 알고리즘으로, 목록의 정수 특성에 따라 적합 할 수 있습니다.
목록의 요소가 그 요소에 대한 전체 순서 관계 만 알고있는 경우 최적 정렬 알고리즘은 복잡도 됩니다. 이것은 매우 멋진 결과이며 온라인에서 쉽게 세부 정보를 찾을 수 있어야합니다. 선형 정렬 알고리즘은 요소 간의 전체 순서 관계가 아니라 정렬 할 요소의 구조에 대한 추가 정보를 활용합니다.
더 일반적으로 정렬 알고리즘의 최적 성은 정렬하려는 목록의 종류 (알고리즘이 실행될 기계 모델뿐만 아니라 정렬이 불량한 경우도 있음)에 대해 가정 할 수있는 가정에 따라 밀접하게 결정됩니다. 알고리즘이 최선의 선택이며, 저장 용 테이프가있는 머신에서는 버블 정렬을 고려하십시오. 가정이 강할수록 알고리즘에서 더 많은 모서리를 줄일 수 있습니다. 목록의 "정렬"을 얼마나 효율적으로 결정할 수 있는지에 대한 매우 약한 가정 하에서 최적의 최악의 경우 복잡도는 있습니다.
이 답변은 복잡성 만 다룹니다. 알고리즘 구현의 실제 실행 시간은 단일 답변에서 설명하기 어려운 많은 요소에 따라 달라집니다.
그와 같은 질문에 대한 대답은 종종 "의존"입니다. (a) 정수의 크기, (b) 입력 배열에 임의의 순서로 정수를 포함하는지 또는 거의 정렬 된 순서로 정수를 포함하는지, (c) 정렬 알고리즘이 안정적인지 여부, (d) 전체 숫자 목록이 메모리 (메모리 내 정렬 대 외부 정렬)에 맞는지 여부 및 (e) 컴퓨터를 실행하는 기계.
실제로, 메모리 내 정렬이 필요한 경우 언어 표준 라이브러리의 정렬 알고리즘이 아마도 아주 좋을 것입니다 (최적에 가깝습니다). 따라서 실제로는 표준 라이브러리에서 제공하는 정렬 기능을 사용하고 실행 시간을 측정하십시오. (i) 정렬이 전체 실행 시간의 큰 부분이고 (ii) 실행 시간이 허용되지 않는 경우에만 정렬 알고리즘을 어지럽히 지 않아도됩니다. 이 두 조건 이 충족되면 특정 도메인의 특정 측면을보고 다른 빠른 정렬 알고리즘을 실험 할 수 있습니다.
그러나 현실적으로 정렬 알고리즘은 거의 큰 성능 병목 현상이 아닙니다.
또한 두 번째 질문에 대답
이론적으로는 더 빠른 것이 가능합니까?
그렇다면 정렬이 가장 복잡하지 않은 것은 무엇입니까?
범용 정렬의 경우 비교 기반 정렬 문제 복잡도는 Ω (n log n) 입니다. O (n)에서 정렬을 수행하는 알고리즘이 있지만 모두 입력에 대한 가정을 기반으로하며 범용 정렬 알고리즘이 아닙니다.
기본적으로 배열을 정렬하는 데 필요한 최소 비교 수에 의해 복잡성이 부여됩니다 (log n은 배열의 각 요소를 비교할 때 작성된 이진 결정 트리의 최대 높이를 나타냄).
정렬 복잡성에 대한 공식적인 증거는 여기에서 찾을 수 있습니다 .
내가 본 최악의 경우에 가장 빠른 정수 정렬 알고리즘은 Andersson et al. 최악의 경우 이며, 물론 O ( n log n ) 보다 빠릅니다 .
이 글을 쓸 당시 다른 두 가지 답변을 읽었으며 어느 쪽이 귀하의 질문에 적절하게 대답하지 않았다고 생각합니다. 다른 답변은 임의 분포와 공간 복잡성에 관한 외래의 아이디어를 고려했는데, 이는 아마도 고등학교 연구 범위를 벗어난 것입니다. 그래서 여기에 내 테이크가 있습니다.
정수 요소 가 n 인 배열 가 주어지면 A 가 정렬 되어 있는지 확인하기 위해 요소 사이를 정확히 ( n - 1 ) 비교 해야합니다 ( 배열의 시작 부분에서 시작하여 마지막 요소와 비교하여 다음 요소를 확인하십시오). 실제로 ( n - 1 ) 비교는 정렬 알고리즘에 가장 적합한 실행 시간입니다 . 즉, 정렬 알고리즘의 실행 시간 하한은 Ω ( n ) 입니다. 기수 정렬 또는 버킷 정렬을 리콜하면 실행 시간이 O ( n . 모든 정렬 알고리즘이 Ω ( n ) 아래로 묶여 있기 때문에기수 정렬과 버킷 정렬이 정수 배열을 정렬하는 가장 빠른 알고리즘이라고 주장합니다.
또한 또는 O ( n )에 익숙하지 않은 경우 : 두 표기법 모두 알고리즘 을 완료하는 데 대략 n 개의 작업 이 필요하다는 것을 의미합니다 ( 2 n 또는 3 n - 5 일 수 있지만 1 또는 n 2 작업은 아님). .
하드웨어에 대한 제한을 언급하지 않고 "가장 빠른"제품을 찾고 있다면 사용 가능한 하드웨어와 입력 종류에 따라 병렬 정렬 알고리즘 중 하나를 선택해야한다고합니다.
이론적으로 예를 들면 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)
참조 :