std::map源码分析
来源:互联网 发布:单片机课程设计目的 编辑:程序博客网 时间:2024/06/07 13:00
默认构造的时候 初始化:
void _Init(){// create head/nil node and make tree empty_Myhead = _Buynode();_Isnil(_Myhead) = true;_Root() = _Myhead;_Lmost() = _Myhead, _Rmost() = _Myhead;_Mysize = 0;}
首先会分配头结点的内存:
_Nodeptr _Buynode(){// allocate a head/nil node_Nodeptr _Wherenode = this->_Alnod.allocate(1);int _Linkcnt = 0;_TRY_BEGINthis->_Alptr.construct(&_Left(_Wherenode), 0);++_Linkcnt;this->_Alptr.construct(&_Parent(_Wherenode), 0);++_Linkcnt;this->_Alptr.construct(&_Right(_Wherenode), 0);_CATCH_ALLif (1 < _Linkcnt)this->_Alptr.destroy(&_Parent(_Wherenode));if (0 < _Linkcnt)this->_Alptr.destroy(&_Left(_Wherenode));this->_Alnod.deallocate(_Wherenode, 1);_RERAISE;_CATCH_END_Color(_Wherenode) = _Black;_Isnil(_Wherenode) = false;return (_Wherenode);}
然后设置颜色为black;设置根节点和最左、最右节点。
2、operator[]操作的时候:
mapped_type& operator[](const key_type& _Keyval){// find element matching _Keyval or insert with default mappediterator _Where = this->lower_bound(_Keyval);if (_Where == this->end()|| this->comp(_Keyval, this->_Key(_Where._Mynode())))_Where = this->insert(_Where,value_type(_Keyval, mapped_type()));return ((*_Where).second);}
第一次插入的,时候lower_bound返回头结点,因为tree是空;
_Where == this->end()为真,执行
_Where = this->insert(_Where,
value_type(_Keyval, mapped_type()));
之后会执行:
iterator insert(const_iterator _Where,const value_type& _Val){// try to insert node with value _Val using _Where as a hint #if _HAS_ITERATOR_DEBUGGINGif (_Where._Mycont != this)_DEBUG_ERROR("map/set insert iterator outside range"); #endif /* _HAS_ITERATOR_DEBUGGING */const_iterator _Next;if (size() == 0)return (_Insert(true, _Myhead, _Val));// insert into empty treeelse if (this->_Multi){// insert even if duplicateif (_Where == begin()){// insert at beginning if before first elementif (!_DEBUG_LT_PRED(this->comp,_Key(_Where._Mynode()), this->_Kfn(_Val)))return (_Insert(true, _Where._Mynode(), _Val));}else if (_Where == end()){// insert at end if after last elementif (!_DEBUG_LT_PRED(this->comp,this->_Kfn(_Val), _Key(_Rmost())))return (_Insert(false, _Rmost(), _Val));}else if (!_DEBUG_LT_PRED(this->comp,_Key(_Where._Mynode()), this->_Kfn(_Val))&& !_DEBUG_LT_PRED(this->comp,this->_Kfn(_Val), _Key((--(_Next = _Where))._Mynode()))){// insert before _Whereif (_Isnil(_Right(_Next._Mynode())))return (_Insert(false, _Next._Mynode(), _Val));elsereturn (_Insert(true, _Where._Mynode(), _Val));}else if (!_DEBUG_LT_PRED(this->comp,this->_Kfn(_Val), _Key(_Where._Mynode()))&& (++(_Next = _Where) == end()|| !_DEBUG_LT_PRED(this->comp,_Key(_Next._Mynode()), this->_Kfn(_Val)))){// insert after _Whereif (_Isnil(_Right(_Where._Mynode())))return (_Insert(false, _Where._Mynode(), _Val));elsereturn (_Insert(true, _Next._Mynode(), _Val));}}else{// insert only if uniqueif (_Where == begin()){// insert at beginning if before first elementif (_DEBUG_LT_PRED(this->comp,this->_Kfn(_Val), _Key(_Where._Mynode())))return (_Insert(true, _Where._Mynode(), _Val));}else if (_Where == end()){// insert at end if after last elementif (_DEBUG_LT_PRED(this->comp,_Key(_Rmost()), this->_Kfn(_Val)))return (_Insert(false, _Rmost(), _Val));}else if (_DEBUG_LT_PRED(this->comp,this->_Kfn(_Val), _Key(_Where._Mynode()))&& _DEBUG_LT_PRED(this->comp,_Key((--(_Next = _Where))._Mynode()), this->_Kfn(_Val))){// insert before _Whereif (_Isnil(_Right(_Next._Mynode())))return (_Insert(false, _Next._Mynode(), _Val));elsereturn (_Insert(true, _Where._Mynode(), _Val));}else if (_DEBUG_LT_PRED(this->comp,_Key(_Where._Mynode()), this->_Kfn(_Val))&& (++(_Next = _Where) == end()|| _DEBUG_LT_PRED(this->comp,this->_Kfn(_Val), _Key(_Next._Mynode())))){// insert after _Whereif (_Isnil(_Right(_Where._Mynode())))return (_Insert(false, _Where._Mynode(), _Val));elsereturn (_Insert(true, _Next._Mynode(), _Val));}}return (insert(_Val).first);// try usual insert if all else fails}
因为if (size() == 0)为真
所以
iterator _Insert(bool _Addleft, _Nodeptr _Wherenode,const value_type& _Val){// add node with value next to _Wherenode, to left if _Addnodeif (max_size() - 1 <= _Mysize)_THROW(length_error, "map/set<T> too long");_Nodeptr _Newnode = _Buynode(_Myhead, _Wherenode, _Myhead,_Val, _Red);++_Mysize;if (_Wherenode == _Myhead){// first node in tree, just set head values_Root() = _Newnode;_Lmost() = _Newnode, _Rmost() = _Newnode;}else if (_Addleft){// add to left of _Wherenode_Left(_Wherenode) = _Newnode;if (_Wherenode == _Lmost())_Lmost() = _Newnode;}else{// add to right of _Wherenode_Right(_Wherenode) = _Newnode;if (_Wherenode == _Rmost())_Rmost() = _Newnode;}for (_Nodeptr _Pnode = _Newnode; _Color(_Parent(_Pnode)) == _Red; )if (_Parent(_Pnode) == _Left(_Parent(_Parent(_Pnode)))){// fixup red-red in left subtree_Wherenode = _Right(_Parent(_Parent(_Pnode)));if (_Color(_Wherenode) == _Red){// parent has two red children, blacken both_Color(_Parent(_Pnode)) = _Black;_Color(_Wherenode) = _Black;_Color(_Parent(_Parent(_Pnode))) = _Red;_Pnode = _Parent(_Parent(_Pnode));}else{// parent has red and black childrenif (_Pnode == _Right(_Parent(_Pnode))){// rotate right child to left_Pnode = _Parent(_Pnode);_Lrotate(_Pnode);}_Color(_Parent(_Pnode)) = _Black;// propagate red up_Color(_Parent(_Parent(_Pnode))) = _Red;_Rrotate(_Parent(_Parent(_Pnode)));}}else{// fixup red-red in right subtree_Wherenode = _Left(_Parent(_Parent(_Pnode)));if (_Color(_Wherenode) == _Red){// parent has two red children, blacken both_Color(_Parent(_Pnode)) = _Black;_Color(_Wherenode) = _Black;_Color(_Parent(_Parent(_Pnode))) = _Red;_Pnode = _Parent(_Parent(_Pnode));}else{// parent has red and black childrenif (_Pnode == _Left(_Parent(_Pnode))){// rotate left child to right_Pnode = _Parent(_Pnode);_Rrotate(_Pnode);}_Color(_Parent(_Pnode)) = _Black;// propagate red up_Color(_Parent(_Parent(_Pnode))) = _Red;_Lrotate(_Parent(_Parent(_Pnode)));}}_Color(_Root()) = _Black;// root is always blackreturn (_TREE_ITERATOR(_Newnode));}
直接插进去了。
[]操作类似一个find操作,如果没有,就分配一个node放在正确的位置,分配颜色, 然后把迭代器的第二个值引用返回,然后再设置。
如果存在,就修改呗。擦擦擦,就是酱紫。
2、如果这样insert的时候:
MyMap testMap; testMap.insert(std::make_pair(1,2)); testMap.insert(std::make_pair(1,4));
第二次就会失败,因为它会先查找到应该插入的地方的上一个节点,如果key相等,就return (_Pairib(_Where, false));
所以不会插入滴。好吧,昨天被同事指出这段代码的问题,今天终于把代码看了下!!
0 0
- std::map源码分析
- std::function源码分析
- Map接口源码分析
- JAVA Map 源码分析
- Map源码分析
- Map接口源码分析
- C++11尝鲜:std::move和std::forward源码分析
- C++11尝鲜:std::move和std::forward源码分析
- C++11:std::move和std::forward源码分析
- C++11尝鲜:std::move和std::forward源码分析
- C++ std::move和std::forward源码分析
- std::map&&std::set
- std::map & std::hash_map
- std::map
- std::map
- std::map
- std::map
- std::map
- 最牛B的编码套路
- 关于一些性能的优化
- .NET中的Drag and Drop操作(二)
- HTC Desire HD刷机卡屏,卡在第一屏解决方案
- MFC中的CApp,CMainFrame,CDoc,CView
- std::map源码分析
- 总结小数格式化DecimalFormat
- Sqlite3 简单使用
- Bus Route
- Android自定义拖拉窗控件
- android-Application的使用-随心
- 地铁摸腿男被抓
- [Android] 性能获取方式-转自淘测试
- GDI坐标系统(下)