오늘의 코드 3일차 에서 알아본 Sort() 함수의 개념에 대해 정리해 보았다.
abstarct
우리는 "오늘의 코드. 3일 (백준/25305번 커트라인)편"에서 Sort() 함수를 다루어 보았다. 굉장히 자주 사용할 만한 함수이고, 생각보다 깊이 파고들면 알 만한 내용도 많았다.
- Sort() 함수의 개념 및 구조
- 심화 내용 (임시객체)
으로 짧게 구성했다. 한번 알아보도록 하자.
Subject 1 - Sort() 함수의 개념 및 구조
Sort() 함수는 C++의 표준 라이브러리 (Standard Template Library = STL)로, 'algorithm' 헤더에 포함되어 있다.
이 함수의 시간 복잡도는 무려 최악의 상황에도 O(nLogn) 으로, 다른 정렬에 비해 빠른 모습을 보여준다.

그 비결은? Quick Sort와 Heap Sort와 Insertion Sort를 잘 섞는 것에 있다.
- Quick Sort로 시작하여서 정렬하다가 재귀의 깊이가 일정수준(2Logn)을 넘어가면 Heap Sort를 이용하여 정렬한다.
- 위의 과정으로 거의 정렬을 마치면, Insertion Sort를 사용하여 완전히 정렬시킨다.
- 다만 위의 과정에서 쪼개진 리스트의 크기가 16이하 (여러번의 실험을 통해 얻어진 결과라고 한다.) 면 Insertion Sort를 진행한다.
리스트의 크기가 충분히 작다면(16이하) Quick Sort 보다 Insertion Sort가 더 빠르기 때문에 애초에 리스트 16이하라면 Insertion Sort만을 사용한다.
Sort 함수의 시간 복잡도는 각 경우에 이렇게 된다.

즉, 항상 O(n log n)이다.
Sort() 함수의 기본적인 용법을 알아보자.
#include <functional>
int main()
{
sort( 시작부분, 끝부분, 비교부분 )
}
시작부분은 배열이나 벡터 등의 시작부분, 끝부분은 끝을 나타낸다. 여기서 자세히 봐야할 부분은 비교부분.
임의로 콜백 함수를 지정하여 오름차순, 내림차순 등의 옵션을 변경 가능하다.
bool comp(int x, int y)
{
return x < y;
}
int main()
{
sort( 시작부분, 끝부분, comp )
}
이런 방식으로 comp 함수를 지정하여 원래 Sort() 함수의 기본 옵션인 오름차순에서 내림차순으로 변경이 가능하다.
이 자리는 Bool형 함수나 수식을 넣어 줄 수 있다.
여기서 더 나아가 "임시 객체"를 이용하여 조금더 간단히 정렬하는 법이 있는데 Subject 2 에서 알아보자.
Subject 2 - 임시 객체
임시 객체란 무엇인가.
말그대로 임시로 사용되는 객체, 즉 실행도중에만 잠깐 썼다 마는 객체이다.
functional 이라는 헤더에는 greater등의 정보가 포함되어있다.
#include <functional>
int main()
{
sort( 시작부분, 끝부분, greater<>() )
}
----- greater의 내부----------
template< class T = void > // 타입은 추론됨 (C++ 14 이후)
struct greater;
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs > rhs;
}
(C++14 이후)
이런 객체를 소스코드에 직접 선언해주는 방법도 있지만, 우리는 Sort() 함수에서만 사용할 것이다. 그렇기에 위와 같이 greater<>()로 Sort안에서만 사용할 임시 객체를 만들어준다.
이전 C++14 이전에서는...
greater<int>()
와 같이 자료형을 명시해주어야 했으나, 이후부터는 Tamplate를 이용한 타입 추론이 가능해지며 필요 없게 되었다.
(파라미터로 들어오는 값의 타입으로 알아서 타입을 추론해준다.)
역으로 오름차순을 나타내는 less<>()도 있다.
template< class T = void >
struct less;
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs < rhs;
}
위의 greater과 비교해서 정확히 부등호 방향만 반대이다.
이는 Sort() 함수에서는 기본값으로 오름차순으로 적용되어있다.
더해서 두개의 배열/벡터 등을 비교하여 같으면 1, 아니면 0을 출력하는 객체인 equal_to<>() 도 있다.
template< class T = void >
struct equal_to;
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs == rhs;
}
Conclusion
Sort() 함수 하나만 해도 생각보다 많은 내용이 담겨있다. 여러가지 정렬방법을 사용하여 시간복잡도를 줄인 것을 보면 우리보다 선배 개발자들이 심혈을 기울여 만든 함수들을 우리는 헤더파일 몇개, 몇 글자 타이핑 하면 편리하게 사용할 수 있다는게 신기했다. 어떤 간단한 함수라도 파고들면 수많은 노력의 결정체라는것을 알 수 있다.
존경스럽다.
혹시 위 정보중에 틀린부분이나 모호한 부분이 있다면 댓글로 알려주길 바란다.
그것이... 댓글이니까...(끄덕)
'코딩 지식' 카테고리의 다른 글
| 오늘의 코딩지식. No. 2 (골드바흐의 추측과 소수판별법) (2) | 2024.02.12 |
|---|