1 栈的定义
栈是限定在表尾进行插入和删除操作的线性表。
2 栈的特点
1)栈是特殊的线性表,线性表也具有前驱后继性;
2)栈的插入和删除操作只能在表尾即栈顶进行;
3)后进先出。
3 栈的实现及关键点
3.1 顺序栈
3.1.1 关键点
1)顺序栈用数组实现,可以将栈底和索引为0的数组空间对齐以降低插入删除操作的空间复杂度;
2)保持栈顶指针top和数组索引一致可降低操作复杂度,空栈的条件是-1 == top,满栈的条件为 栈长-1 == top。
3.1.2 实现
1 #ifndef SQUENCESTACK_H 2 #define SQUENCESTACK_H 3 4 typedef int ElemType; 5 6 class SquenceStack 7 { 8 private: 9 ElemType* m_pData; 10 int m_stackSize; //栈长 11 int m_top; //栈顶指针 12 13 public: 14 SquenceStack(int stackSize); 15 ~SquenceStack(); 16 void ClearStack() { m_top = -1; } //清空栈 17 bool Push(ElemType elem); //压栈 18 bool Pop(ElemType* pElem); //弹栈 19 bool VisitStack() const; //顺序遍历栈 20 bool EmptyStack() const { return -1 == m_top; } //判断是否为空栈 21 }; 22 23 #endif
1 #include "pch.h" 2 #include "SquenceStack.h" 3 #include <iostream> 4 5 SquenceStack::SquenceStack(int stackSize) 6 { 7 m_stackSize = stackSize; 8 m_top = -1; 9 m_pData = new ElemType[stackSize]; 10 } 11 12 SquenceStack::~SquenceStack() 13 { 14 delete[] m_pData; 15 } 16 17 bool SquenceStack::Push(ElemType elem) //压栈 18 { 19 if (m_stackSize - 1 == m_top) //满栈 20 return false; 21 22 ++m_top; 23 m_pData[m_top] = elem; 24 25 return true; 26 } 27 28 bool SquenceStack::Pop(ElemType* pElem) //弹栈 29 { 30 if (EmptyStack()) //空栈 31 return false; 32 33 *pElem = m_pData[m_top]; 34 --m_top; 35 36 return true; 37 } 38 39 bool SquenceStack::VisitStack() const //顺序遍历栈 40 { 41 if (EmptyStack()) 42 { 43 std::cout << "The stack is Empty." << std::endl; 44 return false; 45 } 46 47 48 std::cout << "the element of stack: "; 49 for (int i = 0; i <= m_top; ++i) 50 std::cout << m_pData[i] << ‘ ‘; 51 std::cout << std::endl; 52 53 return true; 54 }
测试代码:
1 #include "pch.h" 2 #include "SquenceStack.h" 3 #include <iostream> 4 5 using namespace std; 6 7 int main() 8 { 9 SquenceStack stack(5); 10 stack.VisitStack(); 11 stack.Push(0); 12 stack.Push(1); 13 stack.Push(2); 14 stack.Push(3); 15 stack.Push(4); 16 stack.VisitStack(); 17 ElemType elem; 18 stack.Pop(&elem); 19 stack.Pop(&elem); 20 stack.VisitStack(); 21 22 return 0; 23 }
测试结果:
3.2 两栈共享空间
3.2.1 适用条件
当两个栈的空间需求有相反关系时,也就是一个栈增长的同时另一个栈在缩短。(增长收缩的快慢应该相同)
3.2.2 实现与关键点
用一个数组来存储两个栈。数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标0处;另一个栈的栈底为数组的末端,即下标为数组长度n-1处。
那么栈1为空时,top1等于-1;栈2为空时,top2等于n;栈满的条件为top1 + 1 == top2。
3.3 链栈
3.3.1 关键点
1)单链表的头指针是必须的,而栈的栈顶指针也是必须的,自然的,可以将头指针和栈顶指针合二为一;
2)链栈为空的条件为nullptr == top,由于只在栈顶进行操作,所以在链表中为了统一操作的哨兵结点失去了作用。
3.3.2 实现
略。
4 栈的应用场景
4.1 四则运算表达式
规则:通过两个栈来实现,其中一个保存操作数的栈,另一个保存运算符的栈。当我们从左到右遍历表达式,当遇到数字,我们就直接压如操作数栈;当遇到运算符,就与运算符栈的栈顶元素进行比较。如果比运算符栈顶元素的优先级高,就将当前运算符压入栈;如果比运算符栈顶元素的优先级低或者相同,从运算符栈中取栈顶运算符,从操作数栈的栈顶取2个操作数,然后计算,再把计算完的结果压入操作数栈,继续比较;其中左括号直接进栈,遇到右括号时运算到匹配到左括号为止。
原文:https://www.cnblogs.com/zpchya/p/10686474.html