정렬(C++)

sort (C++)

정렬은 비교 정렬을 위한 C++ 표준 라이브러리일반적인 기능이다. 함수는 표준 템플릿 라이브러리(STL)에서 비롯되었다.

특정 정렬 알고리즘은 언어 표준에 의해 강제되지 않으며 구현에 따라 다를 수 있지만, 함수의 최악의 경우 가정법적 복잡성이 지정된다.정렬은 N 요소의 범위에 적용될 때 O(N 로그 N) 비교를 수행해야 한다.[1]

사용법

정렬 함수는 C++ 표준 라이브러리의 <알고리즘> 헤더에서 포함되며, 랜덤액세스라는 세 가지 인수를 전달한다.반복기 먼저, RandomAccess반복기 마지막, Compare comp.여기, 랜덤액세스반복기무작위 액세스 반복기가 되어야 하는 템플리트형이며, 번째와 마지막은 반드시 값의 순서를 정의해야 한다. 즉, 증분 연산자를 반복적으로 적용하여 첫 번째부터 첫 번째도달할 수 있어야 한다.또한 템플리트 형식의 세 번째 주장은 비교 술어를 나타낸다.이 비교 술어는 정렬할 시퀀스 요소에 대해 엄격한 미약한 순서를 정의해야 한다.세 번째 인수는 선택 사항이며, 지정하지 않을 경우 C++에서 과부하될 수 있는 "보다 작음"(<) 연산자를 사용한다.

이 코드 샘플은 주어진 정수 배열(오름차순)을 정렬하여 출력한다.

#include <<algorithm>> #include <아이오스트림>  인트로 본래의() {   인트로 배열하다[] = { 23, 5, -10, 0, 0, 321, 1, 2, 99, 30 };   찌꺼기::분류하다(찌꺼기::시작되다(배열하다), 찌꺼기::종지부를 찍다(배열하다));   을 위해 (size_t i = 0; i < 찌꺼기::사이즈를 맞추다(배열하다); ++i) {      찌꺼기::뻐드렁니가 나다 << 배열하다[i] << ' ';   }   찌꺼기::뻐드렁니가 나다 << '\n'; } 

벡터 컨테이너를 사용하는 동일한 기능, 시작종료 방법을 사용하여 반복기:

#include <<algorithm>> #include <아이오스트림> #include <<vector>>  인트로 본래의() {   찌꺼기::벡터<인트로> 송아지 고기 = { 23, 5, -10, 0, 0, 321, 1, 2, 99, 30 };   찌꺼기::분류하다(송아지 고기.시작되다(), 송아지 고기.종지부를 찍다());   을 위해 (size_t i = 0; i < 송아지 고기.사이즈를 맞추다(); ++i) {      찌꺼기::뻐드렁니가 나다 << 송아지 고기[i] << ' ';   }   찌꺼기::뻐드렁니가 나다 << '\n'; } 

제네럴시티

분류는 일반적으로 지정되어 있어서 임의의 임의액세스 컨테이너와 그러한 컨테이너의 요소 x가 다른 요소 y보다 앞에 배치되어야 한다는 것을 결정하는 모든 방법에서 작동할 수 있다.

일반적으로 명시되어 있지만, 정렬이 모든 정렬 문제에 쉽게 적용되는 것은 아니다.일부 연구의 주제가 되어 온 특별한 문제는 다음과 같다.

  • 모든 유효한 지수 i에 대해 요소 A[i]와 요소 B[i] 사이에 어느 정도 관계가 있는 A와 B를 두 배열로 한다.
  • B와의 관계를 유지하면서 A를 분류한다. 즉, A를 분류하는 B에 동일한 순열을 적용한다.
  • AB의 요소를 새로운 으로 복사하여 정렬하고 원래 배열로 다시 이동하지 않고(O(n) 임시 공간이 필요함)를 실행하십시오.

이 문제에 대한 해결책은 A에 의해 제시되었다.2002년에 Williams는 어레이 쌍에 대한 사용자 정의 반복기 유형을 구현하고 그러한 반복기 유형을 올바르게 구현하는 데 있어 몇 가지 어려움을 분석했다.[2]윌리엄스의 해법은 K. 일란더에 의해 연구되고 정제되었다.[3]

복잡성 및 구현

C++ 표준은 N 요소의 범위에 적용될 때 정렬을 위한 호출이 O(N 로그 N) 비교를 수행하도록 요구한다.[4]C++03과 같은 이전 버전의 C++에서는 평균 복잡성만 O(N log N)가 되어야 했다.[5]이는 (중간-of-3) 퀵소트와 같은 알고리즘을 사용할 수 있도록 하기 위한 것으로, 평균적인 경우 속도가 빠르고, 실제로 최적의 최악의 경우 복잡성을 가진 힙 정렬과 같은 다른 알고리즘보다 상당히 빠르며, 최악의 경우 2차 복잡성이 거의 발생하지 않는다.[6]인트로토트와 같은 하이브리드 알고리즘의 도입은 빠른 평균 성능과 최적의 최악의 성능을 모두 허용했고, 따라서 이후의 표준에서는 복잡성 요건이 강화되었다.

구현마다 다른 알고리즘을 사용한다.예를 들어 GNU Standard C++ 라이브러리는 3-part 하이브리드 정렬 알고리즘을 사용한다. introsort는 먼저 수행된다(Introsort 자체가 퀵소트 및 힙 정렬의 하이브리드) 2×log2 n에 의해 주어진 최대 깊이로, 여기서 n은 요소의 수이고, 그 다음에는 결과에 대한 삽입 정렬을 따른다.[7]

기타 정렬 유형

sort안정적이지 않음: 정렬하기 전에 한 방향으로 정렬된 동등한 요소는 정렬 후 다르게 정렬될 수 있다. stable_sort 더 나쁜 성능을 희생시키더라도 결과의 안정성을 보장하며(일부 경우에는 지수 2 - O(n2 logn) - 추가 메모리를 사용할 수 없는 경우 quasilinar 시간만 요구하지만 추가 메모리를 사용할 수 있는 경우 선형 시간 O(n logn n)만 필요하다.[8]이를 통해 안정적인 내부 정렬을 위한 내부 병합 정렬과 추가 메모리와 함께 안정적인 정렬을 위한 정기 병합 정렬을 사용할 수 있다.

부분 정렬은 n 요소의 범위와 정수 m < n을 취하고, 가장 작은 m 원소가 정렬된 순서에 따라 첫 번째 m 위치에 오더하도록(남은 n - m이 일부 불특정된 순서에 따라) 부분 정렬을 실시한다.설계에 따라 이것은 완전한 분류보다 상당히 빠를 수 있다.역사적으로, 이것은 일반적으로 ((n + m log n) 최악의 경우에 걸리는 힙 기반 알고리즘을 사용하여 구현되었다.퀵셀소트라고 불리는 더 나은 알고리즘이 코펜하겐 STL 구현에서 사용되어 복잡성은 ((n + m log m)로 감소한다.[9]

n번째 요소의 선택은 다음을 통해 구현된다.nth_element실제로 내부 부분 정렬을 구현하는 경우: n번째 요소를 올바르게 정렬하고, 또한 이 요소 파티션이 이전 요소보다 작도록 하고, 이후 요소가 더 크도록 보장한다.평균적으로 선형 시간이 걸리지만 최악의 요구사항은 없다. 이러한 요구사항은 피벗 전략의 어떤 선택에서도 선택을 통해 정확히 충족된다.

컨테이너 몇 개, 그중에서.list, 의 전문화된 버전을 제공sort회원으로서이는 링크된 목록이 임의의 액세스 권한을 가지지 못하기 때문이다(따라서 정규 목록을 사용할 수 없음).sort기능) 및 특수 버전은 반복자가 가리키는 값 목록도 보존한다.

qsort와 비교

C++ 표준 라이브러리에는 정렬 외에도 C 표준 라이브러리qsort 기능도 포함되어 있다.qsort에 비해 템플리트 분류qsort처럼 안전하지 않은 보이드 포인터를 통해 데이터 항목에 접근할 필요가 없기 때문에 더 유형 안전하다.또한, qsort는 함수 포인터를 사용하여 비교 함수에 접근하여 많은 수의 반복 함수 호출을 필요로 하는 반면, 정렬적으로 비교 함수는 템플릿 인스턴스화를 위해 생성된 사용자 지정 객체 코드에 삽입될 수 있다.실제로 정렬을 사용하는 C++ 코드는 qsort를 사용하는 등가 C 코드보다 정수처럼 단순한 데이터를 정렬하는 속도가 상당히 빠른 경우가 많다.[10]

참조

  1. ^ "Working Draft, Standard for Programming Language C++" (PDF). ISO. p. 911.
  2. ^ Williams, Anthony (2002). "Pairing off iterators" (PDF). Just Software Solutions.
  3. ^ Åhlander, Krister (2005). Sorting Out the Relationships Between Pairs of Iterators, Values, and References. Proc. Int'l Conf. Generative Programming: Concepts & Experiences. LNCS. Vol. 3676. pp. 342–356. CiteSeerX 10.1.1.184.8947.
  4. ^ "Working Draft, Standard for Programming Language C++" (PDF). ISO. p. 911.
  5. ^ ISO/IEC(2003)ISO/IEC 14882:2003(E): 프로그래밍 언어 C++ §25.3.1.1 정렬 [lib.sort] para.2
  6. ^ 데이비드 머서 "Generic Algorithm",
  7. ^ libstdc++ 설명서:정렬 알고리즘
  8. ^ stabil_stabil
  9. ^ Martínez, Conrado (2004). Partial quicksort (PDF). Proc. 6th ACM-SIAM Workshop on Algorithm Engineering and Experiments and 1st ACM-SIAM Workshop on Analytic Algorithmics and Combinatorics.
  10. ^ Meyers, Scott (2001). Effective STL: 50 specific ways to improve your use of the standard template library. Addison-Wesley. p. 203. ISBN 0-201-74962-9.

외부 링크