数据结构(1)——顺序栈的实现,以及括号匹配的应用
2014-07-26 08:07
507 查看
为什么从堆栈开始?因为我觉得线性部分比较简单的是堆栈和队列,用得也比较多,有不少人觉得链表才简单啊,其实链表简单吗?链表可以派生的东西反而很多,不是一时半会可以理解的,还记得在一篇微软的招聘心得回顾文上看到,微软的面试官就问他怎样用两个链表实现一个栈。当然,现在打乱顺序是因为早在大一就学过数据结构,现在只是更深入更多样的讨论,所以就不再在意一开始教学所用的结构,这不是新手教程。
废话不多说,开始堆栈的学习。
首先,堆栈是线性表的拓展——只能在一头进行修改,所以如果是用高级语言实现的话,可以直接继承LinearList然后进行派生,但是这种方法会产生效率问题,具体看到代码以及注释。
所以我们还是选择直接实现,即自定义一个Stack基类。
接着就来实现括号匹配。括号匹配方法也很多,仅供参考。
因为这个程序不是太复杂,实现的图片就不放上来了(ps:CSDN的传图片功能让人捉急)。
废话不多说,开始堆栈的学习。
首先,堆栈是线性表的拓展——只能在一头进行修改,所以如果是用高级语言实现的话,可以直接继承LinearList然后进行派生,但是这种方法会产生效率问题,具体看到代码以及注释。
所以我们还是选择直接实现,即自定义一个Stack基类。
/*template<class T> class Stack::private LinearList<T>{ //LIFO对象 //没有为Stack类定义析构函数,因此当Stack类型的对象被删除时,自动调用LinearList的析构函数 public: Stack(int MaxStackSize = 10) :LinearList<T>(MaxStackSize) {} bool IsEmpty() const{ return LinearList<T>::IsEmpty(); } bool IsFull() const{ return (Length() == GetMaxSize());//可以在LinearList增加一个保护成员GetMaxSize(), } T Top() const{ if (IsEmpty()) throw OutOfBounds(); T x; Find(Length(), x); return x; } Stack<T>& Add(const T& x){ Insert(Length(), x); return *this; } Stack<T>& Delete(T& x){ LinearList<T>::Delete(Length(), x); return *this; } }; 不幸的是,这类操作会但是一个效率问题。例如: 为了向堆栈中添加一个元素,首先要确定堆栈的长度length(),然后调用函数Insert()。而Insert函数首先必须判断插入操作是否会越界,然后需要付出一个for循环的开销来执行0个元素的移动 而操作符也必须要重载 所以可以把Stack定义成一个基类,而不是派生类 */ template<class T> class Stack{ //LIFO对象 public: Stack(int MaxStackSize = 10); ~Stack(){ delete[] stack; } bool IsEmpty() const { return top == -1; } bool IsFull() const { return top == MaxTop; } T Top() const; Stack<T>& Add(const T& x); Stack<T>& Delete(T& x); private: int top;//栈顶 int MaxTop;//最大的栈顶值 T *stack;//堆栈元素数组 }; template<class T> Stack<T>::Stack(int MaxStackSize){ //Stack类构造函数 MaxTop = MaxStackSize - 1; stack = new T[MaxStackSize]; top = -1; } template<class T> T Stack<T>::Top() const{ //返回栈顶元素 if (IsEmpty()) throw OutOfBounds(); else return stack[top]; } template<class T> Stack<T>& Stack<T>::Add(const T& x){ //添加元素x if (IsFull()) throw NoMem(); stack[++top] = x; return *this; } template<class T> Stack<T>& Stack<T>::Delete(T& x){ //删除元素x if (IsEmpty()) throw OutOfBounds(); x = stack[top--]; return *this; } class OutOfBounds{ public: OutOfBounds() {} }; class NoMem{ public: NoMem(){} }; //使new引发NoMem异常而不是xalloc异常 void my_new_handler(){ throw NoMem(); } std::new_handler Old_Handler_=std::set_new_handler(my_new_handler);程序使用模板函数来定义,和以往的方法不同。说过了这是一次回顾、总结、拓展以及深入,所以和之前的定义不同是难免的。后面的章节还会有不同方法、不同定义的实现,卖关子在这里先。
接着就来实现括号匹配。括号匹配方法也很多,仅供参考。
#include<iostream> #include<string.h> #include<stdio.h> #include"stack.h" using std::cout; using std::cin; using std::endl; const int MaxLength=100;//最大的字符串长度 void PrintMatchedPairs(char *expr){ //括号匹配 Stack<int> s(MaxLength); int j,length=strlen(expr); //从表达式中搜索(和) for(int i=1;i<=length;i++){ if(expr[i-1]=='(') s.Add(i); else if(expr[i-1]==')'){ try{s.Delete(j); cout<<j<<' '<<i<<endl;} catch(OutOfBounds){ cout<<"No match for right parenthesis at "<<i<<endl;} } } //堆栈中所剩下的(都是未匹配的 while(!s.IsEmpty()){ s.Delete(j); cout<<"No match for left parenthesis at "<<j<<endl; } } void main(void){ char expr[MaxLength]; cout<<"Type an expression of length at most "<<MaxLength<<endl; cin.getline(expr,MaxLength); cout<<"The pairs of matching parentheses in"<<endl; puts(expr); cout<<"are"<<endl; PrintMatchedPairs(expr); }
因为这个程序不是太复杂,实现的图片就不放上来了(ps:CSDN的传图片功能让人捉急)。
相关文章推荐
- C/C++数据结构通过顺序栈实现括号()匹配算法
- 8、数据结构笔记之八栈的应用之括号匹配检验实现
- Java堆栈的应用1----------堆栈的自定义实现以及括号匹配算法的Java实现
- 数据结构——顺序栈及其应用(括号匹配)
- 栈的应用-括号匹配-数据结构
- 数据结构之栈的应用:括号匹配问题
- 数据结构课程设计:括号匹配问题(实现检验匹配并输出不匹配的位置)
- IFC标准是为了满足建筑行业的信息交互与共享而产生的统一数据标准,是建 筑行业事实上的数据交换与共享标准。本文概要介绍了IFC标准的产生及发展 历程,IFC的整体框架结构,简要说明了IFC标准的实现方法和过程,描述了 当前的应用以及我们应该更加积极地利用IFC标准为建筑软件行业服务。
- 算法:括号匹配(栈的应用)-数据结构(7)
- 数据结构之---C语言实现括号匹配(栈实现)
- 数据结构(严蔚敏)顺序栈_括号匹配的检验
- 数据结构实现顺序线性表的一些小应用
- 栈的顺序实现以及括号匹配判断程序
- 看数据结构写代码(11)栈的应用(二) 括号匹配的检查
- 数据结构——栈的应用 NOI2.2 括号匹配问题
- 数据结构之 栈的应用 括号匹配
- 数据结构之 栈的应用 括号匹配
- 一、数据结构基础之顺序表C语言实现
- 一、数据结构基础之顺序表C语言实现
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java)