STD: Principle of map sorting

Source: Internet
Author: User

 

Today, I was asked a question by my colleagues. What is the third parameter in map? So I wrote the following program to test it.

#include <map>#include <iostream>using namespace std;typedef map<int,char> icMap;typedef map<int,char>::iterator It;class func{public:func(){};bool operator ()( const int i1, const int i2 ){return i1>i2;}};typedef map<int,char,func> icMapCmp;typedef map<int,char,func>::iterator It1;int main(void){icMap m;m.insert(make_pair(1,'1'));m.insert(make_pair(3,'3'));m.insert(make_pair(2,'2'));for (It it = m.begin();it!=m.end();++it){cout<<it->first<<"\t"<<it->second<<endl;}icMapCmp c;c.insert(make_pair(1,'1'));c.insert(make_pair(3,'3'));c.insert(make_pair(2,'2'));for (It1 it1 = c.begin();it1!=c.end();++it1){cout<<it1->first<<"\t"<<it1->second<<endl;}return 0;}

 

The third parameter msdn is explained as follows:

Traits

The type that provides a function object that can compare two element values as sort keys to determine their relative order in the map. this argument is optional and the binary predicate less <key> is the default value.

As mentioned in msdn, the default value is STD: less.

See the definition of map in stl_map.h:

Template <typename _ key, typename _ TP, typename _ compare = STD: less <_ key>,

Typename _ alloc = STD: Allocator <STD: pair <const _ key, _ TP>

Class Map

The default compare is indeed STD: less, STD: less. In stl_function.h, STD: less is implemented as follows:

 template <class _Tp>    struct less : public binary_function<_Tp, _Tp, bool>    {      bool      operator()(const _Tp& __x, const _Tp& __y) const      { return __x < __y; }};

 

Return _ x <_ y; originally. However, this is only a comparison function. After comparison, how does MAP handle it? It seems that the root cause is still not found.

Then continue tracing. The map constructor:

Map ()

: _ M_t (_ compare (), allocator_type ()){}

When _ M_t is initialized with _ compare (), the _ M_t will be tracked and the red and black trees inside the map will be tracked.

Typedef _ rb_tree <key_type, value_type, _ select1st <value_type>,

Key_compare, _ pair_alloc_type> _ rep_type;

 

/// @ If Maint the actual tree structure. @ endif

_ Rep_type _ M_t;

Finally, the insert_unique function is used:

 template<typename _Key, typename _Val, typename _KeyOfValue,           typename _Compare, typename _Alloc>    pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,   _Compare, _Alloc>::iterator, bool>    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::    insert_unique(const _Val& __v)    {      _Link_type __x = _M_begin();      _Link_type __y = _M_end();      bool __comp = true;      while (__x != 0){  __y = __x;  __comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x));  __x = __comp ? _S_left(__x) : _S_right(__x);}      iterator __j = iterator(__y);      if (__comp)if (__j == begin())  return pair<iterator,bool>(_M_insert(__x, __y, __v), true);else  --__j;      if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v)))return pair<iterator, bool>(_M_insert(__x, __y, __v), true);      return pair<iterator, bool>(__j, false);}

 

The returned value type definition before the function is a bit complicated. In fact, the pair <iterator, bool> is returned, and then compared according to the value _ V to be inserted. If it is true, search for it on the left, or search for it on the right.

 template<typename _Key, typename _Val, typename _KeyOfValue,           typename _Compare, typename _Alloc>    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::    _M_insert(_Base_ptr __x, _Base_ptr __p, const _Val& __v)    {      bool __insert_left = (__x != 0 || __p == _M_end()    || _M_impl._M_key_compare(_KeyOfValue()(__v),       _S_key(__p)));      _Link_type __z = _M_create_node(__v);      _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,      this->_M_impl._M_header);      ++_M_impl._M_node_count;      return iterator(__z);    }

After finding the position, create a node and insert it into the binary balancing tree (that is, the red and black trees.

Hahaha, _ rb_tree_insert_and_rebalance cannot find the code. The following code is found in stlport.

template <class _Key, class _Value, class _KeyOfValue,           class _Compare, class _Alloc> __iterator__ _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> ::_M_insert(_Rb_tree_node_base* __x_, _Rb_tree_node_base* __y_, const _Value& __v,  _Rb_tree_node_base* __w_){  _Link_type __w = (_Link_type) __w_;  _Link_type __x = (_Link_type) __x_;  _Link_type __y = (_Link_type) __y_;  _Link_type __z;  if ( __y == this->_M_header._M_data ||       ( __w == 0 && // If w != 0, the remainder fails to false         ( __x != 0 ||     // If x != 0, the remainder succeeds to true           _M_key_compare( _KeyOfValue()(__v), _S_key(__y) ) ) )       ) {        __z = _M_create_node(__v);    _S_left(__y) = __z;               // also makes _M_leftmost() = __z                                       //    when __y == _M_header    if (__y == this->_M_header._M_data) {      _M_root() = __z;      _M_rightmost() = __z;    }    else if (__y == _M_leftmost())      _M_leftmost() = __z;   // maintain _M_leftmost() pointing to min node  }  else {    __z = _M_create_node(__v);    _S_right(__y) = __z;    if (__y == _M_rightmost())      _M_rightmost() = __z;  // maintain _M_rightmost() pointing to max node  }  _S_parent(__z) = __y;  _S_left(__z) = 0;  _S_right(__z) = 0;  _Rb_global_inst::_Rebalance(__z, this->_M_header._M_data->_M_parent);  ++_M_node_count;  return iterator(__z);}

 

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.