stack和queue的接口比较简单,使用起来也十分方便,只需要注意一个先进先出、后进先出就可以
cpp
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();
}
}
cpp
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遍历的效率
cpp
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;
}
cpp
//队列的模拟实现
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;
};
优先级队列和普通队列主要的不同就在于,出的顺序。优先级高的先出在优先级队列中,普通队列是先进先出。优先级队列的底层实现是一个堆 ,这样子方便弹出优先级高的数据,写一个堆主要是写向上调整函数和向下调整函数,其他地方都比较简单,下面是代码实现
cpp
template<class T, class Container = vector<T>,class Compare = less<T>>
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()(参数)函数,使得这个类的实例化对象可以像函数一样去使用,这就是仿函数,例如
cpp
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;
}
};
这两个类实例化的对象就是调整大堆和小堆的关键,他还在排序算法中被使用
cpp
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 << " ";
}
}