栈是一种特殊的线性表。是只允许在线性表的一端操作的线性表。
栈顶(Top):
栈底(Bottom):
特性:后进先出,先进后出
操作:创建栈Stack(),进栈push(),出栈pop(),获取栈顶元素top(),获取栈大小size(),清空栈clean(),销毁栈~Stack()。
栈接口继承关系图:
Stack.h
/* * Stack: 栈接口 * 成员变量: * push() * pop() * top() * size() * clean() */ #ifndef STACK_H #define STACK_H #include"TopClass.h" namespace DSL { template <typename T> class Stack : public TopClass { public: virtual bool push(const T& obj) = 0; virtual bool pop() = 0; virtual T top() const = 0; virtual int size() const = 0; virtual void clean() = 0; }; } #endif
静态栈:采用顺序存储(数组)实现的栈。
缺点:StaticStack在创建对象时会多次调用元素类的构造函数。
StaticStack.h
/* * StaticStack: 静态栈模板 * 成员变量: * m_space[N]: 栈的存储空间。 * m_top: 栈顶标识符。栈空时m_top=-1。栈满时m_top=capacity-1。 * m_size: 当前栈的大小。 * 成员函数: * StaticStack() 构造函数初始化成员变量 * push() 入栈 * pop() 出栈 * top() 获取栈顶元素 * capacity() 获取栈空间大小 * size() 获取栈的大小 * clean() 清空栈 * ~StaticStack() 清空栈 */ #ifndef STATICSTACK_H #define STATICSTACK_H #include"Exception.h" #include"Stack.h" namespace DSL { template <typename T, int N> class StaticStack : public Stack<T> { protected: T m_space[N]; int m_top; int m_size; public: StaticStack() { m_top = -1; m_size = 0; } void push(const T& obj) { if(m_size < N) { m_space[m_top + 1] = obj; m_top++; m_size++; } else { THROW_EXCEPTION(InvalidOperationException,"error: no space to push!"); } } void pop() { if(m_size > 0) { m_size--; m_top--; } else { THROW_EXCEPTION(InvalidOperationException,"error: no element to pop!"); } } T top() const { if(m_size > 0) { return m_space[m_top]; } else { THROW_EXCEPTION(InvalidOperationException,"error: no element to top!"); } } int capacity() { return N; } int size() const { return m_size; } void clean() { m_size = 0; m_top = -1; } ~StaticStack() { clean(); } }; } #endif
链式栈:采用链表的存储结构实现的栈。
设计:继承自Stack抽象类,组合使用LinkList模板,链表头部为栈顶
LinkListStack.h
/* * LinkListStack: 链表栈模板 * 成员变量: * LinkList<T> m_statcklinklist: 使用链表来 * 成员函数: * LinkListStack(): 不需要构造函数。定义对象时就自动调用链表构造函数。本模板也不使用stack模板的成员变量。 * push(): 链表头部作为栈顶,在链表头部压入元素 * pop(): 删除链表头部的元素 * top(): 返回链表头部的元素 * clean(): 清空链表 * size(): 返回链表长度 */ #ifndef LINKLISTSTACK_H #define LINKLISTSTACK_H #include"Stack.h" #include"LinkList.h" namespace DSL { template <typename T> class LinkListStack : public Stack<T> { protected: LinkList<T> m_liststack; public: void push(const T& obj) { m_liststack.insert(0,obj); } void pop() { if(m_liststack.length() > 0) { m_liststack.remove(0); } else { THROW_EXCEPTION(InvalidOperationException,"error: no element to pop!"); } } T top() const { if(m_liststack.length() > 0) { return m_liststack.get(0); } else { THROW_EXCEPTION(InvalidOperationException,"error: no element to top!"); } } void clean() { m_liststack.clean(); } int size() const { return m_liststack.length(); } }; } #endif
栈的应用:成对符号的匹配。
思路:从第一个字符开始扫描,遇见一般字符时忽略,遇见左符号将其压入栈中,遇见右字符时弹出顶符号,再进行匹配。所有字符扫描完毕且栈为空则成功。