【数据结构笔记】栈

//栈的类定义 
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); 
            }
        } 
    } 
} 
原文地址:https://www.cnblogs.com/zzyh/p/12828228.html