stl中一个特别常用的数据结构就是map,但是相信很多人对map的了解都处于初级阶段,今天我们通过一个一片博文给大家介绍一点map稍微深一点的知识。
我们都知道map的底层是通过红黑树管理节点的,因此map中数据事实上已经是排好序的,但是map是根据什么方法进行排序的呢?今天我们就来聊一聊这个话题。
在日常使用map的过程中我们知道构造一个map需要两个参数,一个是key,一个是value。其实通过map的定义我们不难发现map是需要4个参数的,只不过最后的两个参数stl中给了默认值,一起来看一下:
template<class _Kty,
class _Ty,
class _Pr = less<_Kty>,
class _Alloc = allocator<pair<const _Kty, _Ty> > >
class map
: public _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, false> >
{ // ordered red-black tree of {key, mapped} values, unique keys
public:
typedef map<_Kty, _Ty, _Pr, _Alloc> _Myt;
……
}
通过上面的代码我们发现map需要4个参数,
第一个,key(_Kty);
第二个,value(_Ty);
第三个排序函数对象(_Pr),默认值为:less<_Kty>;
第四个参数(_Alloc)本篇博文不介绍。
这下我们知道了,map默认情况下是通过函数对象less对key值进行排序的。所以如果我们想要改变map的默认排序方式只要在该处将我们自己需要的排序方式的函数对象传递给map就可以了,那什么是函数对象呢?
其实函数对象可以理解为重载了基本运算符的类或结构体(可以通关Stl的源码看看less的定义我们就知道怎么去声明一个函数对象了)
下面我们通过一个实例更清楚的理解一下上面介绍的知识点
#include<map>
#include<vector>
#include<string>
#include<iostream>
#include <algorithm>
using namespace std;
typedef pair<string, int> PAIR;
//运算符重载输出map中迭代器的key和value
ostream& operator<<(ostream& out, const PAIR& p)
{
return out << p.first << "\t" << p.second;
}
//函数对象 greater
template <class T>
struct greater : binary_function<T, T, bool>
{
bool operator()
(const T& x, const T& y) const
{
return x>y;
}
};
int main() {
//map<string, int> name_score_map;
//对key通过函数对象greater实现由大到小的顺序排序
map<string, int, greater<string>> name_score_map;
name_score_map["Zhangsan"] = 90;
name_score_map["Lisi"] = 79;
name_score_map.insert(make_pair("Wangwu", 99));
for (map<string, int>::iterator iter = name_score_map.begin(); iter != name_score_map.end(); ++iter)
{
cout << *iter << endl;
}
return 0;
}
运行结果: