프로그래밍
sort와 stable_sort
친절한티스
2014. 12. 25. 18:58
최근 sort와 stable_sort를 써볼일이 있어서 포스팅해봅니다. 일반적으로 sort 알고리즘을 자주 쓰는데, stable_sort 라는 것도 있더군요. MSDN에 나와있는 stable_sort의 특징으로는 아래와 같습니다.
- 복잡도에 따라 많은 양의 메모리를 필요로 한다
- 최적의 상황(충분한 메모리/정렬된 원소)에서는 O(N log N)의 성능을 보여준다
- 그렇지 못한 경우에는 O( N ( log N )2 )의 성능을 보여준다
- 일반적인 경우 sort가 더 빠르다
- 정렬후 동일값의 원소 순서를 보장 해준다
sort와 stable_sort를 벤치마크한 결과를 보더라도 sort가 더 빠르다는 것을 알수 있습니다. 그렇다면 stable_sort는 언제 쓰는걸까요? sort와 stable_sort의 큰 차이점은 바로 같은 원소값의 순서를 보장해주냐 안해주냐에 있습니다. 이게 무슨 말이냐면 설명 보다 아래 코드의 결과값을 보시면 어떤 차이인지 바로 알수 있습니다.
using namespace std;
class CFoo
{
public:
CFoo(int num,const string &str) : mNum(num),mStr(str) {}
void PrintFoo()
{
cout << mNum << "[" << mStr.c_str() << "] ";
}
int GetNum() const
{
return mNum;
}
private:
int mNum;
string mStr;
};
void PrintVector(const vector<CFoo*> &vec)
{
for (auto it : vec)
{
it->PrintFoo();
}
}
int _tmain(int argc,_TCHAR* argv[])
{
vector<CFoo*> someListForSort{
new CFoo(3, " "), new CFoo(3, " ") , new CFoo(4, " "), new CFoo(2, " ")
, new CFoo(6, " "), new CFoo(3, " ") , new CFoo(5, " "), new CFoo(4, " ")
, new CFoo(2, " "), new CFoo(2, " ") , new CFoo(6, " "), new CFoo(3, " ")
, new CFoo(5, " "), new CFoo(4, " ") , new CFoo(2, " "), new CFoo(6, " ")
, new CFoo(3, " "), new CFoo(5, " ") , new CFoo(1, "A"), new CFoo(1, "B")
, new CFoo(1, "C"), new CFoo(1, "D") , new CFoo(1, "E"), new CFoo(1, "F")
, new CFoo(1, "G"), new CFoo(1, "H") , new CFoo(1, "I"), new CFoo(1, "J")
, new CFoo(4, " "), new CFoo(2, " ") , new CFoo(6, " "), new CFoo(3, " ")
, new CFoo(5, " "), new CFoo(4, " ") , new CFoo(2, " "), new CFoo(6, " ")
, new CFoo(3, " "), new CFoo(5, " ") , new CFoo(4, " "), new CFoo(2, " ")
, new CFoo(2, " "), new CFoo(6, " ") , new CFoo(3, " "), new CFoo(5, " ")
, new CFoo(4, " "), new CFoo(2, " ")
};
vector<CFoo*> someListForStableSort(someListForSort);
// Sort
cout << "Before Sort" << endl;
PrintVector(someListForSort);
cout << endl;
sort(someListForSort.begin(), someListForSort.end(), [](const CFoo* lhs, const CFoo* rhs)->bool {
if (lhs->GetNum() > rhs->GetNum())
return true;
return false;
});
cout << "Aftere Sort" << endl;
PrintVector(someListForSort);
cout << endl;
cout << endl;
// Stable Sort
cout << "Before stable_sort" << endl;
PrintVector(someListForStableSort);
cout << endl;
stable_sort(someListForStableSort.begin(), someListForStableSort.end(), [](const CFoo* lhs, const CFoo* rhs)->bool {
if (lhs->GetNum() > rhs->GetNum())
return true;
return false;
});
cout << "Aftere stable_sort" << endl;
PrintVector(someListForStableSort);
return 0;
}
결과는 아래와 같습니다.
sort로 정렬된 값을 보시면 같은 1의 값을 갖고 있는 알파벳 순서가 뒤바뀐것을 확인할 수 있습니다. 그에 반해 stable_sort는 알파벳 순서가 변하지 않은 것을 확인할 수 있습니다.
참조
http://msdn.microsoft.com/ko-kr/library/z02ba27t.aspx
https://solarianprogrammer.com/2012/10/24/cpp-11-sort-benchmark/
반응형