[C++] STL 정렬 sort 함수 사용법 (오름차순 내림차순) 예제 모음

선택 정렬, 버블 정렬, 퀵 정렬, 병합 정렬, 삽입 정렬 등등 많은 정렬 알고리즘은 많이 존재합니다.

이를 공부하여 코딩 테스트나 대회 또는 실무에서 활용할 수도 있겠지만 정렬 관련 라이브러리를 사용하는 것이 훨씬 효율적이라는 생각이 듭니다.

그래서 본 포스팅에서는 c++ <algorithm> 헤더파일에 속해 있는 sort() 함수에 대해 다루어 보겠습니다.

sort() 함수

  • sort()는 <algorithm> 헤더에 속해 있기때문에 사용하려면 “#include <algorithm>”을 해줘야 합니다.

  • 기본적으로 sort(start, end) 형식으로 호출 되는데, 이는 start를 포함하면서 end를 포함하지 않는 바로 직전까지의 구간을 오름차순으로 정렬합니다.

  • 평균 시간 복잡도는 O(n log n)이며, 이는 quick sort(퀵 정렬)를 기반하는 intro sort로 구현 되어있기 때문입니다. (최악의 경우에도 O(n log n)을 보장합니다.)

  • unstable sort로 중복된 값들의 순서는 정렬하기 전과 다를 수 있습니다.

함수 원형 및 사용법

// 기본 함수 원형
    template <class RandomAccessIterator>  
    void sort (RandomAccessIterator first, RandomAccessIterator last);  
   
// 사용자 정의 함수 원형    
    template <class RandomAccessIterator, class Compare>  
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp); 

아래와 같이 사용할 수 있습니다.

sort(start, end);
sort(start, end, compare); // 사용자가 정의한 기준으로 정렬, compare는 사용자 정의 함수
sort(start, end, greater<자료형>()); // 내림차순 
sort(start, end, less<자료형>()); // 오름차순 

두개의 인자 또는 세개의 인자를 넣어서 함수를 호출할 수 있는데,

(start, end) 범위만 넣은 경우 자동으로 오름차순으로,

(start, end, 함수) 세 개 넣은 경우 함수를 기준으로 정렬할 수 있습니다.

예로, “greater<자료형>()” 함수를 넣어 내림차순으로 정렬할 수도 있고, 사용자 정의 함수를 넣어서 사용자가 정한 정렬 기준을 사용할 수도 있습니다.

이제 예제를 통해 하나씩 사용법을 알아보겠습니다.

예제

배열 오름차순, 내림차순 정렬하기

#include <algorithm> // std::sort
#include <iostream>
using namespace std;

// 배열 출력 함수
void printArray(int *arr, const int n) {
  for (int i = 0; i < n; i++)
    cout << arr[i] << " ";
  cout << endl;
}

int main() {
  const int n = 10;

  // 정렬 전
  cout << "정렬 전" << endl;
  int arr[n] = {3, 9, 2, 6, 1, 5, 7, 8, 0, 4};
  printArray(arr, n);

  // 오름차순 정렬 
  cout << "오름차순 정렬 후" << endl;
  sort(arr, arr + n); 
  printArray(arr, n); // 0 1 2 3 4 5 6 7 8 9

  // 내림차순 정렬 
  cout << "내림차순 정렬 후" << endl;
  sort(arr, arr + n, greater<int>());
  printArray(arr, n); // 9 8 7 6 5 4 3 2 1 0
}

결과값:

array sort

주어진 범위에서만 배열을 정렬합니다. 내림차순으로 정렬하려면 “greater<자료형>()” 함수를 세 번째 인자로 넣어주어 더 큰 요소를 앞에 두는 방식으로 비교하게 합니다.

vector 컨테이너 오름차순, 내림차순 정렬하기

#include <algorithm> // std::sort
#include <iostream>
#include <vector>
using namespace std;

// vector 컨테이너 출력 함수
void printVector(vector<int> &v) {
  for (int i = 0; i < 10; i++) {
    cout << v[i] << " ";
  }
  cout << endl;
}

int main(void) {
  vector<int> v;
  const int n = 10;

  // vector에 1의자리 숫자를 임의로 삽입
  for (int i = 0; i < n; i++) { 
    v.push_back(rand() % 10);
  }

  // 정렬 전
  cout << "정렬 전" << endl;
  printVector(v);

  // 오름차순 정렬
  cout << "오름차순 정렬 후" << endl;
  sort(v.begin(), v.end());
  printVector(v);

  // 내림차순 정렬
  cout << "내림차순 정렬 후" << endl;
  sort(v.begin(), v.end(), greater<int>());
  printVector(v);
}

결과값:

vector sort

주어진 범위에서만 vector 컨테이너를 정렬합니다. 내림차순으로 정렬하려면 “greater<자료형>()” 함수를 세 번째 인자로 넣어주어 더 큰 요소를 앞에 두는 방식으로 비교하게 합니다.

사용자 정의 기준으로 정렬하기

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

// 학생 객체
// 이름하고 나이를 포함
class Student {
public:
  string name;
  int age;
  Student(string name, int age) : name(name), age(age) {}
};

// 사용자 정의 함수
bool compare(Student a, Student b) {
  if (a.name == b.name) { // 이름이 같으면, 나이가 적은순
    return a.age < b.age;
  } else { // 이름이 다르면, 이름 사전순
    return a.name < b.name;
  }
}

// vector 컨테이너 출력 함수
void printVector(vector<Student> &v) {
  for (int i = 0; i < 5; i++) {
    cout << "[" << v[i].name << ", " << v[i].age << "] ";
  }
  cout << endl;
}

int main(void) {
  vector<Student> v;

  v.push_back(Student("민호", 10));
  v.push_back(Student("현준", 24));
  v.push_back(Student("건우", 11));
  v.push_back(Student("원준", 8));
  v.push_back(Student("민호", 13));

  // 정렬 전
  cout << "정렬 전" << endl;
  printVector(v);

  // 사용자 정의 함수로 정렬
  cout << "사용자 정의 함수로 정렬" << endl;
  sort(v.begin(), v.end(), compare);
  printVector(v);
}

결과값:

compare sort

사용자가 직접 정의하는 자체 비교 함수를 작성하여 세 번째 인자로 넣어줄 수도 있습니다. 이 함수는 “첫 번째” 인자가 “두 번째” 인자 앞에 배치되어야 하는지 bool 값을 반환하여 정렬기준을 전달합니다.

“<” 연산자 오버로딩(Operator Overloading)으로 정렬하기

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

// 학생 객체
// 이름하고 나이를 포함
class Student {
public:
  string name;
  int age;
  Student(string name, int age) : name(name), age(age) {}
};

// 연산자 오버로딩 (operator overloading)
bool operator<(Student a, Student b) {
  if (a.name == b.name) { // 이름이 같으면, 나이가 적은순
    return a.age < b.age;
  } else { // 이름이 다르면, 이름 사전순
    return a.name < b.name;
  }
}

// vector 컨테이너 출력 함수
void printVector(vector<Student> &v) {
  for (int i = 0; i < 5; i++) {
    cout << "[" << v[i].name << ", " << v[i].age << "]";
  }
  cout << endl;
}

int main(void) {
  vector<Student> v;

  v.push_back(Student("민호", 10));
  v.push_back(Student("현준", 24));
  v.push_back(Student("건우", 11));
  v.push_back(Student("원준", 8));
  v.push_back(Student("민호", 13));

  // 정렬 전
  cout << "정렬 전" << endl;
  printVector(v);

  // 연산자 오버로딩(Operator Overloading)으로 정렬
  cout << "연산자 오버로딩(Operator Overloading)으로 정렬" << endl;
  sort(v.begin(), v.end());
  printVector(v);
}

결과값:

operator overloading sort

기본적으로 sort() 는 “<” 연산자를 이용하여 값들을 비교해 정렬하는데 연산자 오버로딩을 통해 정렬 기준을 사용자가 원하는 식으로 정의할 수 있습니다. “첫 번째” 인자가 “두 번째” 인자 앞에 배치되어야 하는지 bool 값을 반환하여 정렬기준을 전달합니다.

답글 남기기