map find/count源码分析

参考博客:c++ map find方法源码解析
众所周知,如果一个数据结构想作为map的key,则必须重载 operator < 否则编译将会报错。但是operator == 则是不需要的。那么当查找某个key是否存在的时候,map内部是怎么实现的呢?

结论

为了方便理解,先给出结论(map数据结构红黑树):
1.查找最接近但不小于指定key的节点,并返回该节点,如果该节点不存在则返回end。
2.如果返回节点不是end则将指定的key与返回点进行<比较。返回false则查找的节点成功。返回true,则查找失败。
在这里插入图片描述
示例1:查找key=3的节点,返回5非end,此时将指定key和当前节点比较,即3 < 5,返回True,没找到指定节点。
示例2:查找key=7的节点,返回7非end,此时将指定key和当前节点比较,即7 < 7,返回false,找到指定节点。
示例3:查找key=9的节点,返回end,没找到指定节点。

下面是map源码:

 _NODISCARD iterator find(const key_type& _Keyval) {
        return iterator(_Find(_Keyval), _Get_scary());
    }
 template <class _Other>
    _NODISCARD _Nodeptr _Find(const _Other& _Keyval) const {
        const _Tree_find_result<_Nodeptr> _Loc = _Find_lower_bound(_Keyval);
        if (_Lower_bound_duplicate(_Loc._Bound, _Keyval)) {
            return _Loc._Bound;
        }

        return _Get_scary()->_Myhead;
    }

查找最接近但不小于指定key的节点_Find_lower_bound

 template <class _Keyty>
    _Tree_find_result<_Nodeptr> _Find_lower_bound(const _Keyty& _Keyval) const {
        const auto _Scary = _Get_scary();
        _Tree_find_result<_Nodeptr> _Result{{_Scary->_Myhead->_Parent, _Tree_child::_Right}, _Scary->_Myhead};
        _Nodeptr _Trynode = _Result._Location._Parent;
        while (!_Trynode->_Isnil) {
            _Result._Location._Parent = _Trynode;
            if (_DEBUG_LT_PRED(_Getcomp(), _Traits::_Kfn(_Trynode->_Myval), _Keyval)) {
                _Result._Location._Child = _Tree_child::_Right;
                _Trynode                 = _Trynode->_Right;
            } else {
                _Result._Location._Child = _Tree_child::_Left;
                _Result._Bound           = _Trynode;
                _Trynode                 = _Trynode->_Left;
            }
        }

        return _Result;
    }

如果当前节点不是end则将指定的key和当前节点比较。如果返回false则该节点就是我们需要查找的节点,如果返回true,则表示没找到_Lower_bound_duplicate

 template <class _Keyty>
    bool _Lower_bound_duplicate(const _Nodeptr _Bound, const _Keyty& _Keyval) const {
        return !_Bound->_Isnil && !_DEBUG_LT_PRED(_Getcomp(), _Keyval, _Traits::_Kfn(_Bound->_Myval));
    }

不同版本的stl库的源码实现可能存在差异,但是原理都是相同的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值