Nagie's DevStory
[STL] 08. std::sort 본문
std::sort는 C++ 표준 라이브러리(STL)에서 제공하는 정렬을 수행하는 함수이며, <algorithm> 헤더에 정의되어 있다.
기본적으로 오름차순 정렬을 하며, 퀵 정렬(Quick Sort)이나 병합 정렬(Merge Sort)과 같은 알고리즘으로 구현되어 있다.
기본적인 사용 방법은 다음과 같다.
#include <iostream>
#include <algorithm>
int main() {
int arr[] = { 4, 2, 5, 1, 3 };
std::sort(arr, arr + 5);
for (const auto& e : arr) {
std::cout << e << ", ";
}
}
배열의 시작 지점 메모리 주소와 끝부분의 메모리 주소를 전달하는 형태이다.
위의 코드 같은 경우에는 C 스타일로 작성된 형태이며, C++ 스타일로 작성하고 싶다면 아래의 코드처럼 작성할 수 있다.
//C++ 스타일
std::sort(std::begin(arr), std::end(arr)); //C++ 11부터 사용가능
혹여나 내림차순으로 정렬하고 싶다면 비교 함수 객체를 3번째 인자로 전달해 주면 되는데
C++14 이전 문법은 타입을 명시해 주는 게 권장된다.
//C++ 11
std::sort(std::begin(arr), std::end(arr), std::greater<int>()); // C++14 이전 문법은 타입 명시를 권장함
//C++ 14
std::sort(std::begin(arr), std::end(arr), std::greater<>()); // C++14 부턴 타입 명시를 생략할 수 있음
오름차순으로 정렬할 때 사용하는 비교 함수 객체도 있다.
기본적으로 std::sort가 오름차순으로 정렬하기에 존재감이 없는 수준이긴 하지만 간혹 사용하는 경우도 있으니 작성한다.
std::sort(std::begin(arr), std::end(arr), std::less<>()); //오름차순으로 정렬시 사용
그 외에도 아래의 코드처럼 사용자가 직접 함수를 정의해 3번째 인자에 함수 포인터를 넘겨 정렬하는 방법도 존재한다.
#include <iostream>
#include <vector>
#include <algorithm>
bool abs_cmp(const int a, const int b) {
return std::abs(a) < std::abs(b);
}
int main() {
std::vector<int> nums = { 10, 2, -3, 5, 7 };
sort(nums.begin(), nums.end(), abs_cmp); // [2, -3, 5, 7, 10]
for (const auto& e : nums) {
std::cout << e << ", ";
}
}
사용자 함수를 인자로 넘길 수 있다면 람다식으로도 사용할 수 있다는 이야기이므로
위의 코드를 다음과 같이 작성할 수 있다.
sort(nums.begin(), nums.end(), [] (int a, int b) {
return std::abs(a) < std::abs(b);
}); // [2, -3, 5, 7, 10]
그리고 기본 자료형을 정렬할 때와는 다르게 클래스나 구조체 같은 사용자 정의 자료형을 사용할 때는
아래의 코드 처럼 연산자 오버로딩을 사용해 정렬을 수행해야 한다.
기본 자료형처럼 std::sort를 사용하게 되면 IDE에서 경고 메시지를 띄우거나 컴파일 에러가 발생하게 된다.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
struct Person {
std::string name;
int age;
bool operator<(const Person& a) const {
return this->age < a.age;
}
void print() const {
std::cout << name << ", " << age << std::endl;
}
};
int main() {
std::vector<Person> v;
v.push_back({ "Amelia", 29 });
v.push_back({ "Noah", 25 });
v.push_back({ "Olivia", 31 });
v.push_back({ "Sophia", 40 });
v.push_back({ "George", 35 });
std::sort(v.begin(), v.end());
for (const auto& p : v) {
p.print();
}
}