stack(堆栈)
STL中为了满足一些特定的需求,设计了一些特殊的容器,这些容器提供简单而清晰的接口,例如stack。
stack必须满足先进后出的原则,定义在头文件<stack>中,
namespace std
{
template <class T,class Container=deque<T> >
class stack;
}
第一个template参数代表元素型别。带有默认值的第二个template参数用来定义stack内部存放元素所有的实际容器,缺省采用deque。之所以选择deque而非vector,是因为deque移除元素时会释放内存,并且不必在重新分配时复制全部元素。
stack的核心接口就是三个成员函数push(),top(),pop()
push():将一个元素置于stack内;
top():返回stack内的“下一个”元素;
pop():会从stack中移除顶层元素;
注意:
(1)pop()移除下一个元素,但是并不将它返回;top()返回下一个元素,但是并不移除它。
(2)如果你想移除stack的下一个元素同时并返回它,那么在这两个函数就得调用。
(3)如果stack内没有元素,则执行top()和pop()会导致未定义的行为,你可以采用成员函数size()和empty()来检验容器是否为空。
代码示例:
#include"fuzhu.h"
using namespace std;
int main()
{
stack<int> st;
st.push(1);
st.push(2);
st.push(3);
cout<<st.top()<<" ";
st.pop();
cout<<st.top()<<" ";
st.pop();
st.top()=77;
st.push(4);
st.push(5);
st.pop();
while(!st.empty())
{
cout<<st.top()<<" ";
st.pop();
}
cout<<endl;
system("pause");
return 0;
}
运行结果:
3 2 4 77
可以通过重写stack的一些成员函数,来方便快捷的实现我们需要的操作,比如,我想在pop()元素的同时返回要pop的元素的值,再比如,如果top一个空的stack,会导致未定义的行为,但是我在实际使用过程中,想加入异常处理机制,处理程序运行过程中的异常等等,那么就要自己重新写属于自己的stack类:
stack.h
#ifndef STACK_H
#define STACK_H
#include<deque>
#include<exception>
template<class T>
class Stack
{
protected:
std::deque<T> c;
public:
class ReadEmptyStack:public std::exception//异常处理
{
public:
virtual const char* what() const throw()
{
return "read empty stack";
}
};
typename std::deque<T>::size_type size() const
{
return c.size();
}
bool empty() const
{
return c.empty();
}
void push(const T& elem)
{
c.push_back(elem);
}
T pop()
{
if(c.empty())
{
throw ReadEmptyStack();
}
T elem(c.back());
c.pop_back();
return elem;
}
T& top()
{
if(c.empty())
{
throw ReadEmptyStack();
}
return c.back();
}
};
#endif
#include"stack.h"
#include<iostream>
using namespace std;
int main()
{
try
{
Stack<int> st;
st.push(1);
st.push(2);
st.push(3);
cout<<st.pop()<<" ";
cout<<st.pop()<<" ";
st.top()=77;
st.push(4);
st.push(5);
st.pop();
cout<<st.pop()<<" ";
cout<<st.pop()<<endl;
cout<<st.pop()<<endl;//多pop()了一次,返回异常
}
catch(const exception& e)
{
cerr<<"EXCEPTIONL: "<<e.what()<<endl;
}
system("pause");
return 0;
}
运行结果: