//栈的类定义
const int maxSize=50;
enum bool{false,true};
template<class T>
class Stack
{
public:
Stack(){};
virtual void Push(const T&x)=0;//新元素x进栈
virtual bool Pop(T&x)=0; //栈顶元素出栈,由x返回
virtual bool getTop(T&x)const=0;//读取栈顶元素,由x返回
virtual bool IsEmpty()const=0;//判断栈空
virtual bool IsFull()const=0;//判断栈满
virtual int getSize()const=0;//计算栈中元素的个数
}
//顺序栈类的定义
#include<assert.h>
#include<iostream.h>
#include"stack.h"
const int stackIncreament=20;//栈溢出时扩展空间的增量
template<class T>
class SeqStack:public Stack<T>
{
public:
SeqStack(int sz=50);//建立一个空栈
~SeqStack(){delete[]elements;}//析构函数
void Push(const T& x)
bool Pop(T &x);//如果栈是空的则返回flase
bool getTop(T& x);//如果空则返回false
bool IsEmpty()const{return (top==-1)?true:false;}
bool IsFull()const{return (top==maxSize-1)?true:false;}
int getSize()const (return top+1;)
void MakeEmpty(){top=-1;}
friend ostream& operator << (ostream& os,SeqStack<T>& s);
//输出栈中元素的重载操作
private:
T *elements;
int top;
int maxSize;
void overflowProcess();//栈溢出的处理
};
//顺序栈的构造函数
template<class T>
SeqStack<T>::SeqStack(int sz):top(-1),maxSize(sz)
{
elements=new T[maxSize];
assert(elements!=NULL);//断言机制,若为真程序则继续运行下面的
}
//扩充栈的存储空间
template<class T>
void SeqStack<T>::overflowProcess()
{
T *newarray=new T[maxSize+stackIncreament];
if(newArray==NULL)
{
cerr<<"存储分配失败!"<<endl;
exit(1);
}
for(int i=0;i<=top;i++) newArray[i]=element[i];
maxSize=maxSize+stackIncreament;
delete []elements;
elements=newArray;
}
template<class T>
void SeqStack<T>::Push(const T& x)
{
if(IsFull()==true) overflowProcess();
elements[++top]=x;
}
template<class T>
bool SeqStack<T>::Pop(T& x)
{
if(IsEmpty()==true) return false;
x=elements[top--];
return true;
}
template<class T>
bool Seqstack<T>::getTop(T& x)
{
if(IsEmpty()==true) return false;
x=elements[top];
return true;
}
//输出栈中元素的重载操作
template<class T>
ostream& operator << (ostream& os,SeqStack<T>& s)
{
os<<"top="<<s.top<<endl;
for(int i=0;i<=s.top;i++)
{
os<<i<<":"<<s.elements[i]<<endl;
}
return os;
};
//栈的空间共享 双栈的插入和删除
bool push(DualStack& DS,T x,int d)
//在双栈中扎入元素x,d=0插在第0号栈,d!=0插在第1号栈
{
if(DS.t[0]+1==DS.t[1]) return false;//栈满了
if(d==0) DS.t[0]++;
else DS.t[1]--;
DS.Vector[DS.t[d]]=x;
return true;
};
bool Pop(DualStack& DS,T& x,int d)
//从双栈中推出栈顶元素,通过x返回。d=0从第0号栈推栈,d!=0从第1号栈退栈
{
if(DS.t[d]==DS.b[d]) return false;
x=DS.Vector[DS.t[d]];
if(d==0) DS.t[0]--;
else DS.t[1]++;
return true;
};
//链式栈
#include<iostream.h>
#include"LinkedList.h"
#include"stack.h"
template<class T>
class LinkedStack:public Stack<T> //链式栈类定义
{
public:
LinkedStack():top(NULL){} //构造函数,置空栈
~LinkedStack(){makeEmpty();} //析构函数
void Push(const T&x);
bool Pop(T&x);
bool getTop(T& x);
bool IsEmpty()const{return (top==NULL)?true:false;}
int getSize()const;
void makeEmpty();
friend ostream&operator << (ostream& os,SeqStack<T>& s);
//输出栈中元素的重载操作<<
private:
LinkNode<T>*top; //栈顶指针,即链头指针
};
template<class T>
LinkedStack<T>makeEmpty()
{
//逐次删去链式栈中的元素直至栈顶指针为空
LinkNode<T>*p;
while(top!=NULL)
{
p=top;top=top->link;delete p;
}
};
template<class T>
void LinkedStack<T>::Push(const T& x)
{
top=new LinkNode<T>(x,top);//创建新节点的link为top
assert(top!=NULL);
};
template<class T>
bool LinkedStack<T>::Pop(T& x)
{
if(IsEmpty()) return false;
LinkNode<T>*p=top;
top=top->link;
x=p->data;delete p;
return true;
};
template<class T>
int LinkStack<T>::getTop(T& x)const
{
if(IsEmpty()) return false;
x=top->data;
return true;
}
template<class T>
int LinkedStack<T>::getSize()const
{
LinkNode<T>*p=top;int k=0;
while(top!=NULL)
{
top=top->link;
k++;
}
return k;
};
//输出栈中元素的重载操作
template<class T>
ostream& operator << (ostream& os,LinkedStack<T>& s)
{
os<<"栈中元素的个数="<<s.getSize()<<endl;
LinkNode<T>*p=S.top();int i=0;
while(p!=NULL)
{
os<<++i<<":"<<p->data<<endl;
p=p->link;
}
return os;
};
/*
如果同时使用n个链式栈,其头指针数组可以用一下方式定义:
LinkNode<T>*s=new LinkNode<T>[n];
*/
//栈的应用---括号匹配
#include<iostream.h>
#include<string.h>
#include<stdio.h>
#include"stack.h"
const int maxLength=100;
void PrintMatchedPairs(char *expression)
{
Stack<int>s(maxLength);
int j,length=strlen(expression);
for(int i=1;i<length;i++)
{
if(expression[i-1]=='(') s.Push(i);
else if(expression[i-1]==')')
{
if(s.Pop(j))cout<<j<<"与"<<i<<"匹配"<<endl;
else cout<<"没有与第"<<i<<"个右括号匹配的左括号!"<<endl;
}
}
while(s.IsEmpty()==false)
{
s.Pop(j);
cout<<"没有与第"<<j<<"个左括号相匹配的右括号!"<<endl;
}
}
//栈的应用--表达式计算
#include<math.h>
#include<stack.h>
#include<iostream.h>
class Calculator
{
//模拟一个简单的计算器。此计算机对后缀表达式求值。
public:
Calculator(int sz):s(sz){}
void Run();
void Clear();
private:
Stack<double>s;
void AddOperand(double value); //进操作数栈
bool get2Operands(double& left,double& right);//从栈中退出两个操作数
void DoOperator(char op); //形成运算指令,进行计算
};
void Calculator::DoOperator(char op)
{
//私有函数:取俩个操作数,根据操作符op形成运算指令并计算
double left,right,vlaue;int result;
result=Get2Operands(left,right);
if(result==true)
{
switch(op)
{
case'+':value=left+right;s.Push(value);break;
case'-':value=left-right;s.Push(value);break;
case'*':value=left*right;s.Push(value);break;
case'/':if(right==0.0)
{
cerr<<"Divide by 0!"<<endl;
Clear();
}else{value=left/right;s.Push(value);}
break;
}
}else Clear();
};
bool Calculator::Get2Operands(double& left,double& right)
{
//私有函数:从操作数栈中取出两个操作数。
if(s.IsEmpty()==true)
{
cerr<<"缺少右操作数!"<<endl;
return false;
}
s.Pop(right);
if(s.IsEmpty()==true)
{
cerr<<"缺少左操作数!"<<endl;
return false;
}
s.Pop(left);
return true;
};
void Calculator::AddOperand(double value)
{
s.Push(value);
};
void Calculator::Run()
{
//读取一个字符串并求一个后缀表达式的值。以字符'#'结束。
char ch;double newOperand;
while(cin>>ch,ch!='#')
{
switch(ch)
{
case'+':case'-':case'*':case'/':DoOpertor(ch);break;
default:cin.putback(ch);//将字符放回输入流
cin>>newOperand;
AddOperand(newOperand); //将操作数放入栈中
}
}
};
void Calculator::Clear()
{
S.makeEmpty();
};
//将中缀表达式转换为后缀表达式的算法
void postfix(expression e)
{
/*
把中缀表示e转换成后缀表示并输出,设定e中最后一个符号是'#',而且'#'一开始就放在
栈s的栈底。
*/
Stack<char>s;//定义栈的对象s,其元素为字符。
char ch='#',ch1,op;
s.Push(ch);cin.get(ch);
while(s.IsEmpty()==false&&ch!='#')
{
if(isdigit(ch)) {cout<<ch;cin.get(ch);}//是操作数,输出
else
{
s.getTop(ch1);//从栈顶取出操作符ch1;
if(isp(ch1)<icp(ch)) //新输入操作符ch优先级高
{
s.Push(ch);cin.Get(ch);//进栈,读取下一个字符
}else if(isp(ch1)>icp(ch)) //新输入操作符优先级低
{
s.Pop(op);cout<<op; //退栈并输出
} else
{
s.Pop(op); //输入操作符优先级等于栈顶优先级
if(op=='(') cin.Get(ch);
}
}
}
}