STL---stack 和 queue 容器适配器

模拟实现

1.stack

作为容器适配器,模拟实现当然是用其他容器的了。

namespace bit
{
    template <class T,class Container>
    class stack
    {
    public:
        void push(const T& x)
        {
            _con.push_back(x);
        }

        void pop()
        {
            _con.pop_back();
        }

        T& top()
        {
            return _con.back();
        }

        size_t size()
        {
            return _con.size();
        }

        bool empty()
        {
            return size() == 0;
        }

        void swap(Container& con,Container& ton)
        {
            std::swap(con, ton);
        }


    private:
        Container _con;
    };
}

2.queue

namespace bit
{
    template<class T,class Container>
    class queue
    {
    public:
        void push(const T& x)
        {
            _con.push_back(x);
        }

        void pop()
        {
            _con.pop_back();
        }

        const T& front()
        {
            return _con.front();
        }

        const T& back()
        {
            return _con.back();
        }

        size_t size()
        {
            return _con.size();
        }

        bool empty()
        {
            return size() == 0;
        }

        void swap(Container con, Container ton)
        {
            std::swap(con, ton);
        }

    private:
        Container _con;
    };

3.priority_queue

这东西其实就是 堆 。

template<class T,class Container = vector<int>>
class priority_queue
{
public:
    void push(const T& x)
    {
        _con.push_back(x);
        //这里传的是它的位置
        adjust_up(_con.size() - 1);
    }
    
    //小堆的向上调整
    void adjust_up(T child)
    {
        int parent = (child - 1) / 2;
        while(child > 0)
        {
            if (_con[parent] > _con[child])
            {
                std::swap(_con[parent], _con[child]);
                child = parent;
                parent = (child - 1) / 2;
            }
            else
            {
                break;
            }
        }
    }
    void pop()
    {
        //有效的删除是删除第一个节点,所以得交换
        std::swap(_con[0], _con[_con.size() - 1]);
        _con.pop_back();
        //从0下标开始的向下调整
        adjust_down(0);
    }
    //小堆的向下调整
    void adjust_down(T parent)
    {
        int child = parent * 2 + 1;
        while (child < _con.size())
        {
            /*if (_con[parent] > _con[child] && _con[child] > _con[chlid + 1])
            {
                std::swap(_con[parent], _con[child]);
                parent = child;
                child = parent * 2 + 1;
            }
            if (_con[parent] > _con[child] && _con[child] < _con[chlid + 1])
            {
                std::swap(_con[parent], _con[child]);
                parent = child;
                child = parent * 2 + 1;
            }*/
            //假设法,右孩子存在且左孩子大于右孩子,我就和更小的右孩子交换,就让child++变成右孩子就行
            if (child + 1 < _con.size() && _con[child] > _con[child + 1])
            {
                child++;
            }
            if (_con[parent] > _con[child])
            {
                std::swap(_con[parent], _con[child]);
                parent = child;
                child = parent * 2 + 1;
            }
            else
            {
                break;
            }
        }
    }


    const T top()
    {
        return _con[0];
    }


    size_t size()
    {
        return _con.size();
    }

    bool empty()
    {
        return size() == 0;
    }

private:
    Container _con;
};

这里会发现我写的向上调整和向下调整要适合大堆小堆的话还得修改里面的大于小于符号,但这就太low了,所以有一个办法可以更好的实现这一操作————仿函数。

4.用仿函数改写

template<class T>
class Less
{
public:
    bool operator()(const T& left, const T& right)
    {
        return left < right;
    }
};

template<class T>
class Greater
{
public:
    bool operator()(const T& left, const T& right)
    {
        return left > right;
    }
};
//这儿的话,Compare库里给的缺省是Less,我这里给Greater是因为我建的是小堆懒得改了。
template<class T,class Container = vector<int>,class Compare = Greater<T>>
class priority_queue
{
    //对照上面的看,我写简洁了
    Greater<int> com;
    if (com(_con[parent] , _con[child]))
    if (child + 1 < _con.size() && com(_con[child] , _con[child + 1]))

5.中控deque

https://gitee.com/bithange/110-issues/raw/master/24%E5%B9%B4-01%E6%9C%8823%E6%97%A5--deque+reverse_iteratoer/1-23-%E4%B8%8B%E5%8D%88.png

6.反向迭代器适配器

template<class Iterator,class Ref,class Ptr>
class ReverseIterator
{
public:
    typedef ReverseIterator<Iterator , Ref , Ptr> self;

    Iterator cur;
    

    ReverseIterator(Iterator it)
        :cur(it)
    {}
    

    self& operator++()
    {
        --cur;
        return *this;
    }

    self operator++(int)
    {
        iterator tmp = cur;
        --cur;
        return *tmp;
    }

    self& operator--()
    {
        ++cur;
        return *this;
    }

    self operator--(int)
    {
        iterator tmp = cur;
        ++cur;
        return *tmp;
    }

    Ref operator*()
    {
        ReverseIterator tmp = cur;
        return *--tmp;
    }

    Ptr operator->()
    {
        return &(operator*());
    }
    
    bool operator!=(iterator it)
    {
        return  it != cur;
    }

    bool operator==(iterator it)
    {
        return it == cur;
    }
};

注意:这里的end是最后一个位置的下一个位置,右边那样画是为了对称跟库里一样,正常是:

【有道云笔记】STL---stack 和 queue 容器适配器
https://note.youdao.com/s/ERx1b1Af

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值