模拟stack/queue/priority_queue

stack要点

1.stack遵从先进后出的规则,即先进栈的元素后出栈,入栈/出栈只能在栈的一端进行

2.stack是作为容器适配器被实现的,容器适配器是对特定类进行封装,作为其底层的容器

3.stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器应支持如下操作:
·empty()——判空
·back()——获取尾部元素
·push_back()——尾部插入
·pop_back()——尾部删除

4.标准容器vectordequelist均符合第3条要求,默认情况下,使用deque作为stack的底层容器

5.stack应支持以下操作:
·stack()——构造空栈
·empty()——判断栈是否为空
·size()——返回栈元素数目
·top()——返回栈顶元素引用
·push()——元素入栈
·pop()——栈顶元素出栈

stack模拟

#include <deque>//底层默认使用deque
namespace BL{
	template<class T, class Con = deque<T>>
    class stack {
    public:
        stack() {}
        void push(const T& x) { _c.push_back(x); }
        void pop() { _c.pop_back(); }
        T& top() { return _c.back(); }
        const T& top()const { return _c.back(); }
        size_t size()const { return _c.size(); }
        bool empty()const { return _c.empty(); }
    private:
        Con _c;
    };
}

queue要点

1.queue遵从先进先出的规则,即先入队的元素先出队,入队只能在容器一端,出队只能在容器的另一端

2.queue是作为容器适配器被实现的

3.queue的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器应支持如下操作:
·empty()——判空
·size()——返回队内元素数目
·front()——获取首部元素
·back()——获取尾部元素
·push_back()——尾部插入
·pop_front()——首部删除

4.标准容器dequelist均符合第3条要求,默认情况下,使用deque作为queue的底层容器

5.queue应支持以下操作:
·queue()——构造空队
·empty()——判断队是否为空
·size()——返回队元素数目
·front()——返回队首元素引用
·back()——返回队尾元素引用
·push——从队尾入队
·pop——队首元素出栈

queue模拟

#include <deque>//底层默认使用deque实现
namespace BL{ 
	template<class T, class Con = deque<T>>
    class queue {
    public:
        queue() {}
        void push(const T& x) { _c.push_back(x); }
        void pop() { _c.pop_front(); }
        T& back() { return _c.back(); }
        const T& back()const { return _c.back(); }
        T& front() { return _c.front(); }
        const T& front()const { return _c.front(); }
        size_t size()const { return _c.size(); }
        bool empty()const { return _c.empty(); }
    private:
        Con _c;
    };
}

priority_queue要点

1.priority_queue是一种容器适配器,根据严格的弱排序标准,其第一个元素总是所有元素中最大的

2.priority_queue类似堆,在堆中可以随时插入元素,且只能检索最大堆顶元素(优先队列中位于顶部的元素)

3.priority_queue是作为容器适配器被实现的,元素从特定容器的“尾部”弹出,该“尾部”称为priority_queue的顶部

4.priority_queue的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器应支持随机迭代器访问及如下操作:
·empty()——判空
·size()——返回容器中元素数目
·front()——返回容器中第一个元素的引用
·push_back()——尾部插入
·pop_back()——尾部删除

5.标准容器dequevector均符合第4条要求,默认情况下,使用vector作为priority_queue的底层容器

6.priority_queue应支持以下操作:
·priority_queue()——构造空的优先级队列
·empty()——判断队是否为空
·size()——返回队内元素数目
·top()——返回优先级最高元素的引用
·push——向优先级队列插入元素
·pop——优先级最高元素出栈

7.因支持随机迭代器访问,便于priority_queue维持堆结构,容器适配器应满足下述二者之一即可
a.存在调整算法
b.调用相应算法(make_heap,push_heap,pop_heap)

8.priority_queue<T>——底层构造大堆
priority_queue<T,vector<T>,greater<T>>——底层构造小堆

priority_queue模拟实现

#include <vector>       //底层默认使用vector实现
#include <algorithm>    //调用swap需要
#include <functional>   //greater<T>和less<T>需要

namespace BL{
    template <class T, class Container = vector<T>, class Compare = less<T> >
    class priority_queue{
    public:
        priority_queue() {}
        template <class InputIterator>
        priority_queue(InputIterator first, InputIterator last):c(first,last) {//区间构造
            int curpos = c.size() / 2 - 1;//建堆
            while (curpos >= 0) 
                _AdjustDown(curpos--);
        }
        bool empty() const { return c.empty(); }
        size_t size() const { return c.size(); }
        T& top() const { return c.front(); }
        void push(const T& x) { 
            c.push_back(x);//新增一元素
            _AdjustUp(c.size() - 1);//向上调整算法
        }
        void pop() {
            if (c.empty())
                return;
            swap(c.front(), c.back());//堆顶与堆尾交换
            cout << c.back() << endl;
            c.pop_back();//堆尾出堆
            _AdjustDown(0);//向下调整算法
        }
    private:
        void _AdjustDown(int parent) {
            int n = c.size();
            if (!n)//没有元素可以调整
                return;
            int tmp = c[parent];
            int child = parent * 2 + 1;
            while (child < n) {
                if (child + 1 < n && comp(c[child], c[child + 1]))//寻找合适的孩子
                    ++child;
                if (!comp(c[parent], c[child]))//不符合交换条件
                    break;
                c[parent] = c[child];
                parent = child;
                child = parent * 2 + 1;
            }
            c[parent] = tmp;//入坑
        }
        void _AdjustUp(int child) {
            int tmp = c[child];
            int parent = (child-1) / 2;
            while (child>0) {
                if (comp(tmp,c[parent]))//不符合交换条件
                    break;
                c[child] = c[parent];
                child = parent;
                parent = (child - 1) / 2;
            }
            c[child] = tmp;//入坑
        }
    private:
        Container c;
        Compare comp;
    };  
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值