堆栈是一个线性表,插入和删除只在表的一端进行。这一端称为栈顶(Stack Top),另一端则为栈底(Stack Bottom)。堆栈的元素插入称为入栈,元素的删除称为出栈。由于元素的入栈和出栈总在栈顶进行,因此,堆栈是一个后进先出(Last In First Out)表,即 LIFO 表。
C++ STL 的堆栈泛化是直接通过现有的序列容器来实现的,默认使用双端队列deque的数据结构,当然,可以采用其他线性结构(vector 或 list等),只要提供堆栈的入栈、出栈、栈顶元素访问和判断是否为空的操作即可。由于堆栈的底层使用的是其他容器,因此,堆栈可看做是一种适配器,将一种容器转换为另一种容器(堆栈容器)。
为了严格遵循堆栈的数据后进先出原则,stack 不提供元素的任何迭代器操作,因此,stack 容器也就不会向外部提供可用的前向或反向迭代器类型。
C++ STL 的堆栈泛化是直接通过现有的序列容器来实现的,默认使用双端队列deque的数据结构,当然,可以采用其他线性结构(vector 或 list等),只要提供堆栈的入栈、出栈、栈顶元素访问和判断是否为空的操作即可。由于堆栈的底层使用的是其他容器,因此,堆栈可看做是一种适配器,将一种容器转换为另一种容器(堆栈容器)。
为了严格遵循堆栈的数据后进先出原则,stack 不提供元素的任何迭代器操作,因此,stack 容器也就不会向外部提供可用的前向或反向迭代器类型。
stack堆栈容器的C++标准头文件为 stack ,必须用宏语句 "#include <stack>" 包含进来,才可对 stack 堆栈的程序进行编译。
标准容器库中的堆栈其实是以其他容器作为底层使用,我们也可以按照自己的需要自己修改堆栈,比如想要出栈实现栈中元素的遍历(当然这里不采用其他如list容器),我们就可以自定义一个栈,如下:
#include <iostream>
#include <list>
template<typename T, class C = std::list<T>>
class Stack{
public:
typedef typename C::iterator iterator;
iterator begin(){return cc.begin();}
iterator end() {return cc.end();}
void push(const T& vaule){ cc.push_front(vaule); }
void pop(){cc.pop_front();}
T top(){return cc.front(); }
private:
C cc;
};
int _tmain(int argc, _TCHAR* argv[])
{
Stack<int > FF;
FF.push(9);
FF.push(10);
FF.push(11);
Stack<int>::iterator itor= FF.begin();
while (itor != FF.end())
{
std::cout
<<*itor++<<std::endl;
}
std::cout
<<FF.top()<<std::endl;
FF.pop();
std::cout
<<FF.top()<<std::endl;
FF.pop();
std::cout
<<FF.top()<<std::endl;
FF.pop();
return 0;
}
下面是关于Stack的一些使用:
C++ STL 将这种数据结构和它若干受限制操作用泛型类 stack 容器封装出来,包括堆栈初始化、元素入栈、取栈顶元素、元素出栈、判断堆栈是否非空和取得当前堆栈大小等,应用起来十分容易。
stack的元素出栈操作是不返回栈顶元素的,需要另外通过取栈顶函数获得。这种分离实现是考虑到出栈函数若直接返回栈顶元素,将会导致返回值的数据引用安全问题或不必要的低效复制函数的调用。
从 stack 内部实现看,stack 堆栈是不设最大容量的,但可通过 size 函数获取当前堆栈的大小,以判断是否允许继续让元素入栈,实现具有最大容量限制的堆栈。
#include <stack>
#include <iostream>
using namespace std;
int main()
{
// 创建堆栈对象
stack<int> s;
// 元素入栈
s.push(3);
s.push(19);
s.push(23);
s.push(36);
s.push(50);
s.push(4);
// 元素依次出栈
while(!s.empty())
{
// 打印栈顶元素,打印出:4 50 36 23 19 3
cout << s.top() << endl;
// 出栈
s.pop();
}
return 0;
}
/*堆栈的大小
堆栈的元素个数可用 size 函数获得。每次元素入栈前,先检查当前堆栈的大小,超过某个界限值,
则不允许元素入栈,以此可实现一个具有一定容量限制的堆栈。
size_type size()
返回当前堆栈的元素个数
下面的示例程序,将堆栈的大小设置为 100 个 int 元素,而且使用 list 双向链表做堆栈的底层容器,
每次压入元素时均判断堆栈的大小是否超过100个元素的界限,从而实现具有容量限制的堆栈。
*/
// 限制堆栈的大小
#include <stack>
#include <list>
#include <iostream>
#define STACK_SIZE 100 // 堆栈最大容量
using namespace std;
int main()
{
// 用双向链表作堆栈的底层结构
stack<int, list<int> > s;
// 堆栈未满,元素才能入栈
if (s.size() < STACK_SIZE)
s.push(68);
if (s.size() < STACK_SIZE)
s.push(1);
if (s.size() < STACK_SIZE)
s.push(17);
// 元素出栈
while (!s.empty())
{
// 打印 17 1 68
cout << s.top() << endl;
s.pop();
}
return 0;
}