个人主页:仍有未知等待探索-CSDN博客
专题分栏:C++
一、标准库中的stack(栈)和queue(队列)
1、stack
stack是一种容器适配器。
特点:是先进后出。
常用接口:
函数说明 接口说明 stack() 构造空的栈 empty() 检测stack是否为空 size() 返回stack中元素的个数 top() 返回栈顶元素的引用 push() 将元素val压入stack中 pop() 将stack中尾部的元素弹出
stack<int> s;
// 检测stack是否为空
cout << s.empty() << endl;
// 返回stack中元素的个数
cout << s.size() << endl;
// 返回栈顶元素的引用
cout << s.top();
// 将元素val压入stack中
int val = 1;
s.push(val);
// 将stack中尾部的元素弹出
s.pop();
2、queue
队列是一种容器适配器。
特点:先进先出。
常用接口:
函数声明 接口说明 queue() 构造空的队列 empty() 检测队列是否为空,是返回true,否则返回false size() 返回队列中有效元素的个数 front() 返回队头元素的引用 back() 返回队尾元素的引用 push() 在队尾将元素val入队列 pop() 将队头元素出队列
queue<int> s;
// 检测是否为空
cout << s.empty() << endl;
// 返回queue中元素的个数
cout << s.size() << endl;
// 返回队头的引用
cout << s.front() << endl;
// 返回队尾的引用
cout << s.back() << endl;
// 在队尾将元素val入队列
int val = 1;
s.push(val);
// 将队头元素出队列
s.pop();
3、priority_queue
优先队列是一种容器适配器。
优先队列本质上是一个堆结构。(默认是大堆)
常用接口:
priority_queue()
priority_queue(first,last)
构造一个空的优先级队列 empty( ) 检测优先级队列是否为空,是返回true,否则返回
falsetop( ) 返回优先级队列中最大(最小元素),即堆顶元素 push(x) 在优先级队列中插入元素x pop() 删除优先级队列中最大(最小)元素,即堆顶元素
二、实现
我认为所谓的容器适配器,其实就是一种高级的复用。
用已经实现好的容器作为底层,在此基础上进行封装。
1、stack
// container:容器适配器
// 不需要写构造函数,会默认调用container的构造
// 模板这也可以写缺省参数
//template<class T, class container = vector<T>>
//template<class T, class container = list<T>>
template <class T, class container = deque<T>>
class stack
{
public:
bool empty()
{
return _con.empty();
}
size_t size()
{
return _con.size();
}
T& top()
{
return _con.back();
}
void push(const T& val)
{
_con.push_back(val);
}
void pop()
{
_con.pop_back();
}
private:
container _con;
};
2、queue
//template<class T, class container = list<T>>
template<class T, class container = deque<T>>
class queue
{
public:
bool empty()
{
return _con.empty();
}
size_t size()
{
return _con.size();
}
T& front()
{
return _con.front();
}
T& back()
{
return _con.back();
}
void push(const T& val)
{
_con.push_back(val);
}
void pop()
{
_con.pop_front();
}
private:
container _con;
};
3、priority_queue
template <class T>
class Less
{
public:
bool operator()(const T& x ,const T& y)
{
return x < y;
}
};
template<class T>
class Greater
{
public:
bool operator()(const T& x ,const T& y)
{
return x > y;
}
};
template<class T, class container = vector<T>, class compare = Less<T>>
class priority_queue
{
public:
bool empty()
{
return _con.empty();
}
T& top()
{
return _con.front();
}
void push(const T& val)
{
_con.push_back(val);
adjustUp(_con.size() - 1);
}
void pop()
{
swap(_con.front(), _con.back());
_con.pop_back();
adjustDown(0);
}
private:
void adjustUp(int child)
{
int parent = (child - 1) / 2;
while (child > 0 && compare()(_con[parent], _con[child]))
{
swap(_con[child], _con[parent]);
child = parent;
parent = (child - 1) / 2;
}
}
void adjustDown(int parent)
{
int lchild = parent * 2 + 1;
int rchild = parent * 2 + 2;
while (1)
{
if (lchild >= _con.size() && rchild >= _con.size()) break;
int t = lchild;
if (rchild < _con.size() && compare()(_con[t], _con[rchild])) t = rchild;
if (compare()(_con[parent], _con[t]))
{
swap(_con[parent], _con[t]);
parent = t;
}
else break;
lchild = parent * 2 + 1;
rchild = parent * 2 + 2;
}
}
private:
container _con;
};
三、容器适配器
1、什么是适配器
适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。
stack、queue、priority_queue底层都是容器适配器。
2、什么是deque
deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。
deque通过多个数组实现的。然后由一个中控数组来对每一个小数组进行控制(当然,底层不止这些,了解即可)
deque的底层实现比较复杂,就不过多的解释了 。
四、仿函数
用一个类去实现operator(),使这个类有了类似于函数的行为。
例如:用仿函数去控制优先队列是大堆还是小堆。-> 用仿函数实现大于或小于的判断。
// priority_queue仿函数主体
template <class T>
class Less
{
public:
bool operator()(const T& x ,const T& y)
{
return x < y;
}
};
template<class T>
class Greater
{
public:
bool operator()(const T& x ,const T& y)
{
return x > y;
}
};
// 调用方式
template<class T, class container = vector<T>, class compare = Less<T>>
class priority_queue
{
public:
// 调用一:
T a, b;
compare com;
com(a, b);
// 调用二:
compare()(a, b);
private:
container _con;
};