stack概述
stack是个“后进先出的”数据结构,STL中由class stack<>实作出这样的数据结构,我们可以使用push()将任意数量的元素置入stack中,也可以使用pop()将元素依其次序的反序从容器中移除(即后进先出, LIFO),如图1所示。
图1 Stack的接口
在头文件<stack>中, class stack定义如下:
namesapce std { template<class T, class Container = deque<T>> class stack; }
第一个参数代表元素型别,第二个参数代表stack内部存放元素所用的实际容量,默认采用deque。因为deque在增加元素数量是不存在内存的重新分配,性能比vector高一些。
核心接口
实际上stack是个容器配接器,stack的核心接口就是三个成员函数:push(),top(), pop(),stack接口函数调用都是转化为内部容器成员函数的对应调用,如图2所示。
图2 stack 内部接口
push()
- 将一个元素置入stack内,成为最顶端元素
- 函数无返回值
- 返回stack的最后被插入的元素
- 调用者保证stack不空,否则会导致未定义行为
- 移除stack最后被插入的元素
- 调用者保证stack不空,否则可能导致未定义行为
- 函数无返回值,若想处理被移除的元素,要先调用top函数
stack源码
template<class _Ty, class _Container = deque<_Ty> > class stack { // LIFO queue implemented with a container public: typedef _Container container_type; typedef typename _Container::value_type value_type; typedef typename _Container::size_type size_type; typedef typename _Container::reference reference; typedef typename _Container::const_reference const_reference; stack() : c() { // construct with empty container } explicit stack(const _Container& _Cont) : c(_Cont) { // construct by copying specified container } bool empty() const { // test if stack is empty return (c.empty()); } size_type size() const { // test length of stack return (c.size()); } reference top() { // return last element of mutable stack return (c.back()); } const_reference top() const { // return last element of nonmutable stack return (c.back()); } void push(const value_type& _Val) { // insert element at end c.push_back(_Val); } void pop() { // erase last element c.pop_back(); } const _Container& _Get_container() const { // get reference to container return (c); } protected: _Container c; // the underlying container };
stack 运用实例
/**************************************************************** *函数名称:StackTest *功 能:stack 使用说明 *作 者:Jin *日 期:2016年7月1日 ****************************************************************/ void StackTest() { stack<int> st; //push three elements into the stack st.push(1); st.push(2); st.push(3); //pop and print two elements from the stacks cout << st.top() << ' '; st.pop(); cout << st.top() << ' '; st.pop(); //modify top element st.top() = 77; //push two new elements st.push(4); st.push(5); //pop one element without processing it st.pop(); //pop and print remaining elements while (!st.empty()) { cout << st.top() << ' '; st.pop(); } cout << endl; //output: 3 2 4 77 }
自定义的Stack Class
标准的stack<> class 将运行速度置于方便性和安全性上,但使用上却不方便,若操作标准的stack,并且stack中无元素时会导致程序奔溃,出现程序未定义行为。我们可自己编写一个stack class,它可以有以下优势:
1.pop()会返回下一个元素
2.如果stack为空,pop()和top()会抛出异常。
3.可自行删增成员函数,简化操作方法
user_stack源码
它在.h文件中声明和实现,引用user_stack时,需要includ“user_stack.h”文件,其源码如下:
#ifndef _USER_STACKH_ #define _USER_STACKH_ #include <deque> #include <exception> template <class T> class user_stack { public: class ReadEmptyStack: public std::exception { public: virtual const char * what() const throw() { return "read empty stack"; } }; //number of element typename std::deque<T>::size_type size() const { return c.size(); } //is stack empty bool empty() const { return c.empty(); } //push element into stack void push(const T &elem) { c.push_back(elem); } //pop element out of stack and return is value T pop() { if (c.empty()) { throw ReadEmptyStack(); } T elem(c.back()); c.pop_back(); return elem; } //return top value T& top() { if (c.empty()) { throw ReadEmptyStack(); } return c.back(); } protected: std::deque<T> c; }; #endif /*_USER_STACKH_*/
user_stack应用
/**************************************************************** *函数名称:UserStackTest *功 能:user_stack模板使用实例 *作 者:Jin *日 期:2016年7月9日 ****************************************************************/ void UserStackTest() { try { user_stack<int> UsersStack; //push three elements into the stack UsersStack.push(1); UsersStack.push(2); UsersStack.push(3); //pop and print two elements from the stack cout << UsersStack.pop() << ' '; cout << UsersStack.pop() << ' '; //modify top element UsersStack.top() = 77; //push two new elements UsersStack.push(4); UsersStack.push(5); //pop one element without processing it UsersStack.pop(); //pop and print three elements cout << UsersStack.pop() << ' '; cout << UsersStack.pop() << endl; cout << UsersStack.pop() << endl; } catch (const exception& e) { cerr << "Exception : " << e.what() << endl; } //output: // 3 2 3 77 // Exception : read empty stack }