stack和queue的接口比较简单,使用起来也十分方便,只需要注意一个先进先出、后进先出就可以
- void test_queue()
- {
- queue<int> qe;
- qe.push(1);
- qe.push(2);
- qe.push(3);
- qe.push(4);
- qe.push(5);
- while (!qe.empty())
- {
- cout << qe.front() << "-";
- qe.pop();
- }
- }
- void test_stack()
- {
- stack<int> st;
-
- st.push(1);
- st.push(2);
- st.push(3);
- st.push(4);
- while (!st.empty())
- {
- cout << st.top() << "-";
- st.pop();
- }
- cout << endl;
- }
这是他们的使用比较简单,这里不再赘述。下面来讲他的底层实现,底层可以使用很多容器去实现他比如vector、只需要注意这两个适配器都不允许遍历。他的底层实现主要是来自于一个新的容器deque(双向队列)这是一个集合了vector和list的优点的容器,缺点就是遍历效率太低导致他无法代替vector。
这里可以测试一下deque和vector遍历的效率
- void test_deque()
- {
- deque<int> d;
- vector<int> v;
- srand(time(nullptr));
- for (int i = 0; i < 10000; i++)
- {
- int randnums = rand();
- d.push_back(randnums);
- v.push_back(randnums);
- }
- size_t begin1 = clock();
- sort(d.begin(), d.end());
- size_t end1 = clock();
-
- size_t begin2 = clock();
- sort(v.begin(), v.end());
- size_t end2 = clock();
-
- cout << end1 - begin1<< endl;
- cout << end2 - begin2 << endl;
-
- }
- //队列的模拟实现
- template<class T, class Container>
- class queue
- {
- public:
- void push(const T& x)
- {
- _con.push_back(x);
- }
- void pop()
- {
- _con.pop_front();
- }
- bool empty()
- {
- return _con.empty();
- }
- size_t size()
- {
- return _con.size();
- }
- T& back()
- {
- return _con.back();
- }
- T& front()
- {
- return _con.front();
- }
- //栈的模拟实现
- template<class T, class Container>
- class stack
- {
- public:
- void push(const T& x)
- {
- _con.push_back(x);
- }
- void pop()
- {
- _con.pop_back();
- }
- size_t size()
- {
- return _con.size();
- }
- T& top()
- {
- return _con.back();
- }
- bool empty()
- {
- return _con.empty();
- }
- private:
- Container _con;
- };
优先级队列和普通队列主要的不同就在于,出的顺序。优先级高的先出在优先级队列中,普通队列是先进先出。优先级队列的底层实现是一个堆,这样子方便弹出优先级高的数据,写一个堆主要是写向上调整函数和向下调整函数,其他地方都比较简单,下面是代码实现
- template<class T, class Container = vector
,class Compare = less> - class priority_queue
- {
- public:
- void Adjustup(int child)
- {
- Compare com;
- int parent = (child - 1) / 2;
- while (child>0)
- {
- if (com(_con[parent], _con[child]))
- {
- swap(_con[child], _con[parent]);
- child = parent;
- parent = (child - 1) / 2;
- }
- else
- break;
- }
- }
- void Adjustdown(int parent)
- {
- size_t child = parent * 2 + 1;
- Compare cmp;
- while (child < _con.size())
- {
- if (child + 1 < _con.size () && cmp(_con[child],_con[child+1]))
- child++;
- if (cmp(_con[parent] , _con[child]))
- {
- swap(_con[child], _con[parent]);
- parent = child;
- child = parent * 2 + 1;
- }
- else
- break;
- }
- }
- void push(const T& x)
- {
- _con.push_back(x);
- Adjustup(_con.size() - 1);
- }
- void pop()
- {
- swap(_con[0], _con[_con.size() - 1]);
- _con.pop_back();
- Adjustdown(0);
- }
- T& top()
- {
- return _con[0];
- }
- size_t size()
- {
- return _con.size();
- }
- bool empty()
- {
- return _con.empty();
- }
- private:
- Container _con;
- };
仿函数主要是写一个类重载operator()(参数)函数,使得这个类的实例化对象可以像函数一样去使用,这就是仿函数,例如
- template<class T>
- struct less
- {
- bool operator()(T& e1, T& e2)
- {
- return e1 < e2;
- }
- };
- template<class T>
- struct greater
- {
- bool operator()(T& e1, T& e2)
- {
- return e1 > e2;
- }
- };
这两个类实例化的对象就是调整大堆和小堆的关键,他还在排序算法中被使用
- void test_sort()
- {
- vector<int> v;
- v.push_back(1);
- v.push_back(4);
- v.push_back(3);
- v.push_back(6);
- v.push_back(7);
- //默认升序
- sort(v.begin(), v.end());
- for (auto nums : v)
- {
- cout << nums << " ";
- }
- cout << endl;
- //调成降序
- sort(v.begin(), v.end(), greater<int>());
- for (auto nums : v)
- {
- cout << nums << " ";
- }
- }