链式栈
Link Stack
//栈的链式存储 //就是单链表; 受限的单链表, 一般不需要带头结点 #include<iostream> #include<string> using namespace std; //链式栈中每个节点的定义 template<typename T> struct StackNode { T data; //数据域 StackNode<T>* next; //指针域,指向下一个同类型节点 }; //链式栈的定义 template<typename T> class LinkStack { public: LinkStack(); //构造函数 ~LinkStack(); //析构函数 public: bool Push(const T& e); //入栈 bool Pop(T& e); //出栈 bool GetTop(T& e); //读取栈顶元素,但该元素没有出栈 void DispList(); //输出链式栈中的所有元素 int ListLength(); //获取链式栈的长度 bool Empty(); //判断栈是否为空 private: StackNode<T>* m_top; //栈顶指针 int m_length; //链式栈当前场长度 }; template<typename T> LinkStack<T>::LinkStack() { m_top = nullptr; m_length = 0; } //入栈操作 template<typename T> bool LinkStack<T>::Push(const T& e) { StackNode<T> *node = new StackNode<T>; node->data = e; node->next = m_top; m_top = node; m_length++; return true; } //出栈,也就是删除栈顶数据 template<typename T> bool LinkStack<T>::Pop(T& e) { if(Empty() == true) return false; StackNode<T>* p_willdel = m_top; m_top = m_top->next; e = p_willdel->data; delete p_willdel; m_length--; return true; } //读取栈顶元素,但是该元素并没有出栈,而是依旧在栈中 template<typename T> bool LinkStack<T>::GetTop(T& e) { if(Empty() == true) return false; e = m_top->dat; return true; } //输出栈中的所有元素 template<typename T> void LinkStack<T>::DispList() { if(Empty() == true) return ; StackNode<T>* p = m_top; while(p != nullptr) { cout << p->data << " "; p = p->next; } cout << endl; } //获取链式栈的长度 template<typename T> int LinkStack<T>::ListLength() { return m_length; } //判断是否为空 template<typename T> bool LinkStack<T>::Empty() { if(m_top == nullptr) return true; return false; } //析构函数 template<typename T> LinkStack<T>::~LinkStack() { StackNode<T> * temp = m_top; while(m_top) { m_top = m_top->next; delete temp; temp = m_top; } } int main() { // LinkStack<int> myobj; // myobj.Push(12); // myobj.Push(24); // myobj.Push(48); // myobj.Push(100); // myobj.DispList(); // int temp = 0; // myobj.Pop(temp); // myobj.DispList(); cout << "-------------下面是括号匹配的例子-------------------" <<endl; bool ifMatchSucc = true; //是否匹配成功的标志,先标记匹配成功 LinkStack<char> matchobj; string strExp = "[({}){}]"; for(size_t i = 0; i < strExp.size(); ++i) { if(strExp[i] == '(' || //左括号全部入栈 strExp[i] == '[' || strExp[i] == '{') { matchobj.Push(strExp[i]); } else { //当前是个又括号,则从栈顶去除一个左括号 char tempchar; if(matchobj.Pop(tempchar) == false) // 从栈顶取出数据失败 { ifMatchSucc = false; break; } //取得了栈顶的一个左括号,看一看是否匹配 if((strExp[i] == ')' && tempchar == '(') || (strExp[i] == ']' && tempchar == '[') || (strExp[i] == '}' && tempchar == '{') ) { continue; } else { ifMatchSucc = false; break; } } }//end for; //扫描完成,还要确定matchobj栈为空才可以 if(ifMatchSucc == true && matchobj.Empty() == false) { ifMatchSucc = false; } if(ifMatchSucc == true) { cout << "\"" <<strExp << "\"格式合法,括号配对数量和顺序都正确" << endl; } else { cout << "\"" <<strExp << "\"格式非法,括号配对数量和顺序不正确" << endl; } return 0; } //栈存在的意义和引用举例 //a)保存临时数据,函数调用栈,栈帧 //b)利用栈来进行括号匹配 //c)计算表达式结果,利用栈把中缀表达式转换成后缀表达式(逆波兰表达式),然后再次利用栈对后缀表达式得到最终结果
欢迎大家指出博文中的错误哦。

浙公网安备 33010602011771号