tl; dr : 이중 연결 목록에서 quicksort를 효율적으로 구현할 수 있습니까? 그것에 대해 생각하기 전에 나의 이해는 아니었다.빠른 정렬 반복기 요구 사항
요 전날은 기본 정렬 알고리즘에 대한 반복기 요구 사항을 고려할 기회가있었습니다. 기본적인 O (N²) 것들은 상당히 간단합니다.
- 버블 정렬 - 2 개의 순방향 반복자는 다른 하나를 드래그하면서 멋지게 수행합니다.
- 삽입 정렬 - 2 개의 양방향 반복자가 수행합니다. 하나는 순서가 잘못된 요소이고 하나는 삽입 포인터입니다.
- 선택 정렬 - 좀 더 까다 롭지만 앞으로 반복자가 트릭을 수행 할 수 있습니다.
은 퀵는
표준 : 종류의 introsort_loop (는 GNU 표준 라이브러리/마력 (1994)에서와 같이/실리콘 그래픽 (1996)) random_access 수를 필요로한다.
__introsort_loop(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Size __depth_limit, _Compare __comp)
예상대로.
이제 더 자세히 살펴보면 quicksort에 이것을 요구하는 실제 이유를 찾을 수 없습니다. 명시 적으로 random_access_iterator가 필요한 유일한 것은 std::__median
호출이며 중간 요소를 계산해야합니다. 일반 바닐라 퀵 소트 은 중간 값을 계산하지 않습니다.
파티셔닝은 체크
if (!(__first < __last))
return __first;
정말
하지 bidirectionalS를위한 유용한 검사로 구성되어 있습니다. 그러나 하나
if (__first == __last) this_partitioning_is_done = true;
의 간단한 조건 (오른쪽 왼쪽/왼쪽에서 오른쪽으로) 이전 파티션 여행 수표와 이것을 대체 할 수 있어야하는 것이 가능에만 양방향 반복자를 사용하여 매우 효율적으로 퀵을 구현하는 것입니다 ? 재귀 깊이는 여전히 지켜 질 수 있습니다.
NB. 나는 아직 실제 구현을 시도하지 않았다.
삽입 정렬의 경우 순방향 반복기로 충분합니다. 'std :: rotate'와'std :: upper_bound'의 조합을 사용하여 삽입을 구현할 수 있으며, 두 성분 모두 순방향 반복자 만 필요합니다. 물론 여전히 O (N^2)입니다. – TemplateRex