stack的介绍和使用
1.1stack的介绍
1.stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入和提取操作。 2.stack是作为容器适配器被实现的,容器适配器是对特定类封装作为其底层指定的容器,并提供一组特定的成员函数来访问其元素。 3.stack的底层容器可以是任何标准的容器类模板或者其他特定的容器类。这些容器类支持以下操作: 1.empty:判空 2.back:获取尾部元素 3.push_back:尾部插入元素 4.pop_back:尾删 4.标准容器vector,deque,list均符合要求,默认情况下使用deque。 5.关于适配器:适配器是一种设计模式,该模式是将一个类的接口转化为客户需要的另一种接口 参考电源适配器
1.2stack的使用
函数说明 | 节后说明 |
---|---|
stack() | 构造空栈 |
empty() | 判空 |
size() | 求个数 |
top() | 返回栈顶元素的引用 |
push() | 压栈 |
pop() | 删除栈尾元素 |
1.3stack的模拟实现
主要实现的就是push, pop, top, size, empty
#include <iostream>
#include <assert.h>
#include <deque>
using namespace std;
namespace bit
{
template<class T,class Container = deque<T>>
//模板,默认的容器是deque
class stack
{
public:
//尾插
void push(const T& val)
{
_con.push_back(val);
}
//尾删
void pop()
{
_con.pop_back();
}
//top
const T& top()
{
return _con.back();
}
//size
size_t size()
{
return _con.size();
}
//判断为空
bool empty()
{
return _con.empty();
}
private:
Container _con;
};
}
queue的介绍和使用
1.队列是一种容器适配器,专门用在先进先出中操作,从容器一段插入元素,另一端提取元素。 2.队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从队尾入队列,从对头出队列。 3.底层容器可以是标准的容器之一,也可以是其他专门设计的容器类,但必须支持一下接口: empty,size,front,back,push_back,pop_back; 4.标准容器类dequeue和list满足以上需求,默认使用的容器是dequeue。
queue的使用
函数声明 | 接口说明 |
---|---|
queue() | 构造空队列 |
empty() | 判空 |
size() | 返回对抗i俄中有效元素的个数 |
front() | 返回队头元素的引用 |
back() | 返回队尾元素的引用 |
push() | 在队尾将元素val如队列 |
pop() | 将队头元素出队列 |
queue的模拟实现
主要实现empty, size, push, back, front, back, pop
#pragma once
#include<iostream>
#include<deque>
using namespace std;
namespace bit
{
template<class T,class Container = deque<T>>
class queue
{
public:
void push(const T& val)
{
_con.push_back(val);
}
void pop()
{
_con.pop_front();
}
const T& front()
{
return _con.front();
}
const T& back()
{
return _con.back();
}
size_t size()
{
return _con.size();
}
bool empty()
{
return _con.empty();
}
private:
Container _con;
};
}
priority_queue的介绍及使用
priority_queue的介绍
1.优先级队列是哟中容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。 2.类似于堆,可以检索出最大堆元素(堆顶) 3.queue提供出一组特定的成员函数来访问其元素,元素从特定容器的“尾部”弹出,其称为优先级队列的顶部。 4.底层容器可以是任何标准的的类模板,也可以是自定义的类模板。容器可以通过随机访问迭代器访问,并支持一下操作: empty(), size(),front(),push_back(),pop_back(). 5.vector && deque满足要求,默认使用vector。 6.需要支持随机访问迭代器,以便始终在内部保持对结构,容器适配器通过在需要时自动调用算法函数make_heap, push_heap, pop_heap来自动完成操作。
priority_queue的使用
优先级队列默认使用vector作为其底层容器,在vector上又使用了堆算法将vector中元素构成堆的结构,因此priority_queue就是堆,所有用到堆的位置,都可以考虑priority_queue。priority_queue默认情况下是大堆
函数声明 | 借口说明 |
---|---|
priority queue()/priority queue(first,last) | 构造一个空的优先级队列 |
empty() | 判空 |
top() | 返回堆顶元素 |
push(x) | 插入x |
pop() | 删除堆顶元素 |
模拟实现priority_queue
【注意】 1.默认情况下,priority_queue是大堆。 2.如果在priority_queue中放自定义类型的数据,需要在自定义类型中提供> 或者< 的重载。 补充:仿函数 优点:仿函数可在多种情况下替代函数指针。
namespace A
{
template<class T>
struct less
{
//重载()
bool operator()(const T& x, const T& y)
{
return x < y;
}
};
template<class T,class Compare = less<T>>
class B
{
public:
B(int a = 10)
:_a(a)
{}
void test(const T a)
{
//if (a < _a)
//等价于
Compare cmp;
if(cmp(a,_a))
{
cout << "<" << endl;
}
}
private:
T _a;
};
}
void test2()
{
A::B<int> b;
b.test(1);
}
int main()
{
test2();
return 0;
}
模拟代码:
#pragma once
#include<iostream>
#include<assert.h>
#include<vector>
#include<functional>
using namespace std;
namespace bit
{
//优先级队列,大堆< ,小堆 >
template<class T,class Container = vector<T>,class Compare = less<T>>
class priority_queue
{
public:
void push(const T& val)
{
_con.push_back(val);
//向上调整AdjustUp
AdjustUp(_con.size() - 1);
}
void pop()
{
assert(_con.size() > 0);
swap(_con[0], _con[_con.size() - 1]);
_con.pop_back();
//向下调整建大堆
AdjustDown(0);
}
//top
const T& top()
{
return _con[0];
}
//size
size_t size()
{
return _con.size();
}
//empty
bool empty()
{
return _con.empty();
}
private:
Container _con;
protected:
void AdjustUp(int child)
{
Compare cmp;
int parent = (child - 1) / 2;
while (child > 0)
{
//if (_con[parent] < _con[child])
if(cmp(_con[parent] , _con[child]))
{
swap(_con[parent], _con[child]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
void AdjustDown(int parent)
{
Compare cmp;
size_t child = parent * 2 + 1;
while (child < _con.size())
{
if (child + 1 < _con.size() && cmp(_con[child] , _con[child + 1]))
{
child = child + 1;
}
//if (_con[parent] < _con[child])
if(cmp(_con[parent] , _con[child]))
{
swap(_con[parent], _con[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
//完成less && greater
template<class T>
struct less
{
bool operator()(const T& x, const T& y)
{
return x < y;
}
};
template<class T>
struct greater
{
bool operator()(const T& x, const T& y)
{
return x > y;
}
};
};
}