Stack queue
namespace OO
{
template<class T,class container = vector<T>>
class Stack
{
public:
void push(const T& x)
{
_v.push_back(x);
}
void pop()
{
_v.pop_back();
}
const T& top()
{
return _v.back();
}
size_t size()
{
return _v.size();
}
bool empty()
{
return _v.empty();
}
private:
container _v;
};
template<class T,class Container = list<T>>
class queue
{
public:
void push(const T& x)
{
_list.push_back(x);
}
void pop()
{
_list.pop_front();
}
const T& front()
{
return _list.front();
}
const T& back()
{
return _list.back();
}
ssize_t size()
{
return _list.size();
}
bool empty()
{
return _list.empty();
}
private:
Container _list;
};
}
deque
deque,double ended queue即双端队列,是一种在两端均可以扩展或者收缩的序列化容器。
deque可以在头部和尾部进行插入和删除操作。deque容器存储数据的空间是由一段一段等长的连续空间构成,各段空间之间并不一定是连续的,可以位于在内存的不同区域,使用一个中控器(指针数组)map来指向这些一段一段的空间,如果当前段空间用完了,就添加一个新的空间并将它链接在头部或尾部
优点 缺点
deque特殊的存储结构使得它在头部和尾部插入删除元素的效率非常高,deque可以在头部再加一段空间存储元素,而vector由于采取一段连续存储空间存储元素,所以它在头部插入一个元素需要所有元素向后移动,效率极低。
但是也正式因为deque这种特殊的存储结构,使得它的迭代器较于一般的迭代器更为复杂,虽然deque容器的迭代器也支持随机访问,但是访问元素的速度要低于vector。
deque的迭代器
迭代器有4个指针:
cur--当前指向的数据位置
first、last--buff数组(存储数据的数组)开始和结束
node--指向中控数组(map数组)
优先级队列
优先级队列的使用
定义一个priority_queue。打印出1-9从大到小 从小到大?
怎么调用仿函数改变大堆为小堆?#include<iostream> #include<string> #include<queue> #include<functional> using namespace std; void test() { //默认是大堆 priority_queue<int> pq; pq.push(1); pq.push(3); pq.push(5); pq.push(6); pq.push(8); pq.push(9); while (!pq.empty()) { cout << pq.top() << " "; pq.pop(); } cout << endl; } void test2() { //改参数变成小堆 //greater--仿函数参数 priority_queue<int, vector<int>, greater<int>> pq;//模板第三个改变为小堆,但是必须先传入第二个参数才能改第三个参数。 pq.push(1); pq.push(3); pq.push(5); pq.push(6); pq.push(8); pq.push(9); while (!pq.empty()) { cout << pq.top() << " "; pq.pop(); } cout << endl; } int main() { test2(); test(); return 0; }
优先级队列的模拟实现
模拟实现接口函数
namespace OO
{
template<class T>
struct Less
{
};
template<class T>
struct Greater
{
};
//模板参数
class priority_queue
{
public:
priority_queue()
{}
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last)
{
}
void AdjustDown(int parent)
{
}
void AdjustUp(int child)
{
}
bool empty() const
{
}
size_t size() const
{
}
const T& top() const
{
}
void push(const T& x)
{
}
void pop()
{
}
private:
};
}
模拟实现
注意点:
1.模板中的优先级队列默认是大根堆
2.priority_queue<int,vector<int>,greater<int>>是小根堆
3.仿函数的写法理解是谁小谁向下调整
namespace OO
{
template<class T>
struct Less
{
bool operator()(const T& x,const T& y)
{
return x < y;
}
//大根堆情况是谁小谁向下调整,x小所以x向下交换
};
template<class T>
struct Greater
{
bool operator()(const T& x, const T& y)
{
return x > y;
}
};
//模板参数
template<class T,class Container = vector<int>,class com = Less<int>>
class priority_queue
{
public:
priority_queue()
{}
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last)
:_con(first,last)
{
for (int i = ((_con.size() - 2) / 2); i >= 0; --i)
{
Adjustdown(i);
}
}
void AdjustDown(int parent)
{
int child = 2 * parent + 1;
int n = _con.size();
com compare;
while (child < n)
{
if (child + 1 < n && compare(_con[child] , _con[child + 1])) child++;
if (compare(_con[parent], _con[child]))
{
std::swap(_con[parent], _con[child]);
parent = child;
child = 2 * parent + 1;
}
else
{
break;
}
}
}
void AdjustUp(int child)
{
int parent = (child-1) / 2 ;
while (child > 0)
{
com compare;
if (compare(_con[parent], _con[child]))
{
std::swap(_con[parent], _con[child]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
bool empty() const
{
return _con.size() == 0;
}
size_t size() const
{
return _con.size();
}
const T& top() const
{
return _con[0];
}
void push(const T& x)
{
_con.push_back(x);
AdjustUp(_con.size() - 1);
}
void pop()
{
std::swap(_con[0], _con[_con.size() - 1]);
_con.pop_back();
AdjustDown(0);
}
private:
Container _con;
};
}
仿函数
仿函数需要重载 ()运算符 ,仿函数--指的是把对象当做函数
仿函数是模板函数,其速度比一般函数要慢
struct Less
{
bool operator()(int x, int y)
{
return x < y;
}
};
int main()
{
Less lessFunc;
cout << lessFunc(1, 2) << endl;
return 0;
}