栈是一种容器适配器,特别为后入先出而设计的一种(LIFO ),那种数据被插入,而后再容器末端取出。ios
默认状况下,若是没有容器类被指定成为一个提别的stack 类,标准的容器类模板就是deque 队列。数据结构
堆栈是一个线性表,插入和删除只在表的一端进行。这一端称为栈顶(Stack Top),另外一端则为栈底(Stack Bottom)。堆栈的元素插入称为入栈,元素的删除称为出栈。因为元素的入栈和出栈总在栈顶进行,所以,堆栈是一个后进先出(Last In First Out)表(queue是FIFO),即 LIFO 表。函数
实现C++ STL,栈有两个参数:spa
template < class T, class Container = deque<T> > class stack;
参数示意:设计
T: 元素类型 Container: 被用于存储和访问元素的的类型
C++ STL 的堆栈泛化是直接经过现有的序列容器来实现的,默认使用双端队列deque的数据结构。
code
固然,能够采用其余线性结构(vector 或 list等),只要提供堆栈的入栈、出栈、栈顶元素访问和判断是否为空的操做便可。orm
因为堆栈的底层使用的是其余容器,所以,堆栈可看作是一种适配器,将一种容器转换为另外一种容器(堆栈容器)。对象
为了严格遵循堆栈的数据后进先出原则,stack 不提供元素的任何迭代器操做,所以,stack 容器也就不会向外部提供可用的前向或反向迭代器类型。队列
拓展:element
Q:为何stack和queue没有迭代器?让这些容器具有迭代器岂不是更方便?
A:一个容器的方法与其自己特性密切联系,stack和queue分别是FILO和FIFO的线性表,不容许其余的进出方式,为了严格遵照这种原则,故不提供迭代器操做。deque是双向队列,提供迭代器。
stack堆栈容器的C++标准头文件为 stack ,必须用宏语句 "#include <stack>" 包含进来,才可对 stack 堆栈的程序进行编译。
使用堆栈前,先要利用构造函数进行初始化,建立一个堆栈对象,以进行元素的入栈、出栈等操做。 1. stack() 默认构造函数,建立一个空的 stack 对象。 例如,下面一行代码使用默认的 deque 为底层容器,建立一个空的堆栈对象 s 。 stack<int> s; 2. stack(const stack&) 复制构造函数,用一个 stack 堆栈建立一个新的堆栈。 例如,下面的代码利用 s1 ,建立一个以双向链表为底层容器的空堆栈对象 s2 。 // stack<int, list<int> > s1; stack<int, list<int> > s2(s1);
stack堆栈容器的元素入栈函数为push函数。
因为 C++ STL 的堆栈函数是不预设大小的,所以,入栈函数就不考虑堆栈空间是否为满,均将元素压入堆栈,从而函数没有标明入栈成功与否的返回值。
以下是他的使用原型:
void push(const value_type& x) void push ( const T& x );
示例:
// stack::push/pop #include <iostream> #include <stack> using namespace std; int main () { stack<int> mystack; for (int i=0; i<5; ++i) mystack.push(i); cout << "Popping out elements..."; while (!mystack.empty()) { cout << " " << mystack.top(); mystack.pop(); } cout << endl; return 0; } //output:Popping out elements... 4 3 2 1 0
stack容器的元素出栈函数为 pop 函数,因为函数并无判断堆栈是否为空,才进行元素的弹出,所以,须要自行判断堆栈是否为空,才可执行 pop 函数。
void pop()
示例:
下面的示例代码,将堆栈的全部元素所有出栈 // stack<int> s; while(!s.empty()) { s.pop();// 出栈 }
// stack::push/pop #include <iostream> #include <stack> using namespace std; int main () { stack<int> mystack; for (int i=0; i<5; ++i) mystack.push(i); cout << "Popping out elements..."; while (!mystack.empty()) { cout << " " << mystack.top(); mystack.pop(); } cout << endl; return 0; } //output:Popping out elements... 4 3 2 1 0
(4)取栈顶元素
value_type& top()
value_type& top ( ); const value_type& top ( ) const;
示例:
// test_stack.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include <stack> #include <vector> #include <deque> #include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { stack<int> mystack; mystack.push(10); mystack.push(20); mystack.top()-=5; cout << "mystack.top() is now " << mystack.top() << endl; return 0; } //output: mystack.top() is now 15
随着堆栈元素不断出栈,堆栈可能会出现空的状况,所以,通常须要调用 empty 函数判断是否非空,才做元素出栈和取栈顶元素的操做。
bool empty() //判断堆栈是否为空,返回 true 表示堆栈已空,false 表示堆栈非空。
示例:
// stack::empty #include <iostream> #include <stack> using namespace std; int main () { stack<int> mystack; int sum (0); for (int i=1;i<=10;i++) mystack.push(i); while (!mystack.empty()) { sum += mystack.top(); mystack.pop(); } cout << "total: " << sum << endl; return 0; } //output:55
堆栈的元素个数可用 size 函数得到。每次元素入栈前,先检查当前堆栈的大小,超过某个界限值,则不容许元素入栈,以此可实现一个具备必定容量限制的堆栈。
size_type size ( ) const; //计算栈对象元素个数
示例:
// stack::size #include <iostream> #include <stack> using namespace std; int main () { stack<int> myints; cout << "0. size: " << (int) myints.size() << endl; for (int i=0; i<5; i++) myints.push(i); cout << "1. size: " << (int) myints.size() << endl; myints.pop(); cout << "2. size: " << (int) myints.size() << endl; return 0; } //output: 0. size: 0 1. size: 5 2. size: 4