C++(STL源码刨析/stack/queue/priority_queue)

一 stack

template <class T,class Sequence = deque<T>>
class stack
{
    // 判断 2 个 stack 是否相等/小于
    friend bool operator== __STL_NULL_TMPL_ARGS(const stack&,const stack&);
    friend bool operator< __STL_NULL_TMPL_ARGS(const stack&,const stack&);

    public:
    // stack 直接拿配接器内的类型用
    typedef typename Sequence::value_type value_type;
    typedef typename Sequence::size_type size_type;
    typedef typename Sequence::reference reference;
    typedef typename Sequence::const_reference const_reference;
    
    protected:
    // 配接器
    Sequence c;
    
    public:
    // 判空/元素个数/栈顶元素/入栈/弹栈
    bool empty() const { return c.empty(); }
    size_type size() const { return c.size(); }
    reference top() { return c.back(); }
    void push(const value_type& x) { c.push_back(x); }
    void pop() { c.pop_back(); }
};

template<class T,class Sequence>
bool operator==(const stack<T,Sequence>& x,const stack<T,Sequence>& y)
{
    // 配接器 == 配接器
    return x.c == y.c;
}

template<class T,class Sequence>
bool operator<(const stack<T,Sequence>& x,const stack<T,Sequence>& y)
{
    // 配接器 < 配接器
    return x.c < y.c;
}

二 queue

template <class T,class Sequence = deque<T>>
class queue
{
    // 判断 2 个 stack 是否相等/小于
    friend bool operator== __STL_NULL_TMPL_ARGS(const queue&,const queue&);
    friend bool operator< __STL_NULL_TMPL_ARGS(const queue&,const queue&);

    public:
    // queue直接拿配接器内的类型用
    typedef typename Sequence::value_type value_type;
    typedef typename Sequence::size_type size_type;
    typedef typename Sequence::reference reference;
    typedef typename Sequence::const_reference const_reference;
    
    protected:
    // 配接器
    Sequence c;
    
    public:
    // 判空/元素个数/栈顶元素/入栈/弹栈
    bool empty() const { return c.empty(); }
    size_type size() const { return c.size(); }
    reference front() { return c.front(); }
    const_reference front() const { return c.front(); }
    reference back() { return c.back(); }
    const_reference back() const { return c.back(); }
    void push(const value_type& x) { return c.push_back(x); }
    void pop() { c.pop_front(); }
};

template<class T,class Sequence>
bool operator==(const queue<T,Sequence>& x,const queue<T,Sequence>& y)
{
    // 配接器 == 配接器
    return x.c == y.c;
}

template<class T,class Sequence>
bool operator<(const queue<T,Sequence>& x,const queue<T,Sequence>& y)
{
    // 配接器 < 配接器
    return x.c < y.c;
}

三 priority_queue

template <RandomAccessIterator>
//  堆插入
inline void push_heap(RandomAccessIterator first,RandomAccessIterator last)
{
    // 调用该接口时,已经有新元素插入到了末尾
    //             迭代器首/尾  元素距离类型          元素类型
    __push_heap_aux(first,last,distance_type(first),value_type(first));
}

template <RandomAccessIterator,class Distance,class T>
inline void __push_heap_aux(RandomAccessIterator first,RandomAccessIterator last,
                                                       Distance*,T*)
{
    //    迭代器首     指向最后一个元素的下标         下标 0       最后一个元素
    __push_heap(first,Distance((last - first) - 1),Distance(0),T(*(last - 1)));
}

template <RandomAccessIterator,class Distance,class T>
void __push_heap(RandomAccessIterator first,Distance holeIndex,Distance topIndex,T value)
{
    // 根据孩子节点求父节点 (index - 1) / 2
    Distance parent = (holeIndex - 1) / 2;
    // 如果孩子节点下标至少大于 0 ,并且父节点小于新插入尾部的元素
    while(holeIndex > topIndex && *(first + parent) < value)
    {
        // 让孩子节点 == 父节点,这里没有直接交换,也能达到交换的效果
        // 只要条件满足,尾部节点就会一直被移动,那么可以直接最开始就把尾部节点值拷贝保存起来
        // 最后结束循环在在孩子节点上赋值即可
        *(first + holeIndex) = *(first + parent);
        // 更新孩子节点
        holeIndex = parent;
        // 重新计算父子节点
        parent = (holeIndex - 1) / 2;
    }
    // 最后在让孩子节点 = 最开始尾部从插入的值
    *(first + holeIndex) = value;
}

template <class RandomAccessIterator>
inline void pop_heap(RandomAccessIterator first,RandomAccessIterator last,T*)
{
    __pop_heap_aux(first,last,value_type(first));
}

template <class RandomAccessIterator,class T>
inline void __pop_heap_aux(RandomAccessIterator first,RandomAccessIterator last,T*)
{
    __pop_heap(first,last - 1,last - 1,T(*(last - 1),distance_type(first));
}

template <class RandomAccessIterator,class T,class Distance>
inline void __pop_heap(RandomAccessIterator first,RandomAccessIterator last,
                       RandomAccessIterator result,T value,Distance*)
{
    // 尾部 = 头部元素
    *result = *first;
    __adjust_heap(first,Distance(0),Distance(last - first),value);
}

template <class RandomAccessIterator,class Distance,class T>
void __adjust_heap(RandomAccessIterator first,RandomAccessIterator holeIndex,
                                              Distance len,T value)
{
    // 原数组尾元素不计入
    // 0
    Distance top_Index = holeIndex;
    // 右孩子节点    
    DIstance secondChild = 2 * holeIndex + 2;
    // 孩子节点 < 最大长度
    while(secondChile < len)
    {
        // 左比右大 -- 孩子节点
        if(*(first + secondChild) < *(first + (secondChild - 1)))
            secondChild--;
        
        // 孩子赋值给父
        *(first + holeIndex) = *(first + secondChild);
        
        // 更新孩子,父节点
        // 此时父是空洞节点,即无效节点
        holeIndex = secondChild;
        secondChild = 2 * (secondChild + 1);
    }
    
    // 如果叶子节点只有左节点,边界处理
    if(secondChild == len)
    {
        *(first + holeIndex) = *(first + (secondChild - 1));
        holeIndex = secondChild - 1;
    }
    
    // 最后父节点就是空洞节点,在该节点上进行向上调整,结束给空洞节点赋值
    __push_heap(first,holeIndex,topIndex,value);
}

template <class T,class Sequence = vector<T>,
          class Compare = less<typename Sequence::value_type>>
class priority_queue
{
    public:
    // priority_queue直接拿配接器内的类型用
    typedef typename Sequence::value_type value_type;
    typedef typename Sequence::size_type size_type;
    typedef typename Sequence::reference reference;
    typedef typename Sequence::const_reference const_reference;
    
    // 配置器/比较方法
    protected:
    Sequence c;
    Compare comp;

    // 无参构造/自定义比较函数构造
    public:
    priority_queue() :c() {}
    explicit priority_queue(const Compare& x) :c(),comp(x) {}
    
    // 迭代器区间制造和自定义比较方法
    template <class InputIterator>
    priority_queue(InputIterator first,InputIterator last,const Compare& x)
        :c(first,last)
        ,comp(x)
        { make_heap(c.begin(),c.end(),comp); }
    
    // 迭代器区间构造
    template <class InputIterator>
    priority_queue(InputIterator first,InputIterator last)
        :c(first,last)
        { make_heap(c.begin(),c.end(),comp); }
    
    // 判空/元素总个数/堆顶元素/插入/删除
    bool empty() const { return c.empty(); }
    size_type size() const { return c.size(); }
    const_reference top() const { return c.front(); }
    void push(const value_type& x)
    {
        // 看上面
        __STL_TRY
        {
            c.push_back(x);
            push_heap(c.begin(),c.end(),comp);
        }
        // 异常处理
        __STL_UNWIND(c.clear();)
    }
    void pop()
    {
        // 看上面
        __STL_TRY
        {
            pop_heap(c.begin(),c.end(),comp);
        }
        // 异常处理
        __STL_UNWIND(c.clear());
    }
};

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值