c++实验4 栈及栈的应用+回文+中、后缀表达式

 栈及栈的应用+回文+中、后缀表达式

1、栈顺序存储结构的基本操作算法实现

1)栈顺序存储结构的类定义:

class SeqStack
{
private:
    int maxsize;
    DataType *data;      //顺序堆栈数组
    int top;                                            //栈顶位置指示器
public:
    SeqStack(int size);      //构造函数
    ~SeqStack(void) {}            //析构函数
    void Push(const DataType item);      //入栈
    DataType Pop(void);                  //出栈
    DataType GetTop(void)const;      //取栈顶数据元素
    void GetAll();
    void Destory();
    void ClearAll();
    int NotEmpty(void)const            //堆栈空否
    {return(top==-1);};
    int Full(void)const             //堆栈满否
    {return(top==maxsize-1);};
};

2)构造栈算法

输入:栈元素个数的最大数size

初始化栈:栈顶指示置为-1,创建存储栈的数组,栈元素个数的最大数maxsize置 为size;

SeqStack::SeqStack(int size)
{
    top=-1;
    maxsize=size;
    data=new DataType[maxsize];
}

3)获得栈顶元素算法

输入:无

前置条件:栈不空

动作:取栈顶数据元素给e

输出:返回栈顶元素值e

后置条件:无

DataType SeqStack::GetTop(void)const           //取栈顶数据元素
//取当前栈顶数据元素并返回
{
    if(top==-1)
    {
        cout<<"堆栈空!"<<endl;
        exit(0);
    }
    DataType e=data[top-1];
    return e;                        //返回当前栈顶元素
}

4)进栈算法

输入:要进栈的项item

前置条件:栈未满

动作:把item压入栈顶

输出:无

后置条件:栈顶增加一个新元素,栈顶指示加1;

void SeqStack::Push(const DataType item)       //入栈
//把元素item入栈;堆栈满时出错退出
{
    if(top==maxsize)
    {
        cout<<"堆栈已满!"<<endl;
        exit(0);
    }
    data[top]=item;                       //先存储item
    top++;                                //然后top加1
}

5)出栈算法

输入:无

前置条件:栈非空

动作:删除栈顶元素

输出:返回删除的栈顶元素值

后置条件:删除栈顶元素,栈顶指示减1

DataType SeqStack::Pop()                       //出栈
//出栈并返回栈顶元素;堆栈空时出错退出
{
    if(top==-1)
    {
        cout<<"堆栈已空!"<<endl;
        exit(0);
    }
    top--;                             //top先减1
    return data[top];                 //然后取元素返回
}

6)遍历栈算法

输入:无

前置条件:栈非空

动作:遍历输出每个栈非空元素

输出:无

后置条件:无

void SeqStack::GetAll()
{
    if(top==-1)
    {
        cout<<"堆栈已空!"<<endl;
        exit(0);
    }
    for(int i=top-1;i>=-1;i--)
    {
        cout<<data[i]<<" ";
    }
    cout<<endl;
}

7)销毁栈算法

输入:无

前置条件:栈存在

动作:删除存储栈元素的数组

输出:无

后置条件:栈的存储元素区域不存在,栈顶指针归-1,maxsize为0

void SeqStack::Destory()
{
    top=-1;

    delete data;
    cout<<"栈的存储元素区域不存在"<<endl;
    maxsize=0;
}

8)清空栈算法

输入:无

前置条件: 无

动作:清空栈,栈顶指示器归-1;

输出:无

后置条件:栈顶指示为-1

void SeqStack::ClearAll()
{
    top=-1;
}

上机实现以上基本操作,写出main()程序:

#include <iostream>
typedef int DataType;
#include"SeqStack.h"
using namespace std;
int main()
{
    SeqStack stack1335(10);
    DataType test[]={2,4,6,8,10};
    for(int i=0;i<5;i++)
        stack1335.Push(test[i]);
     cout<<"入栈"<<endl;
    while(!stack1335.NotEmpty())
        cout<<stack1335.Pop()<<" ";
    cout<<"出栈"<<endl;
    for(int i=0;i<5;i++)
        stack1335.Push(test[i]);
    cout<<"入栈"<<endl;
    stack1335.ClearAll();
    cout<<"清空所有"<<endl;
    stack1335.GetAll();
    return 0;
}

 

2、用以上基本算法,实现:void conversion()

将输入10进制数转化为2进制和8进制数

void SeqStack::conversion(int num)
{
    int a=num;
    while(a)
    {
        Push(a%2);
        a/=2;
    }
    cout<<"转换为二进制:";
    GetAll();
    ClearAll();
    while(num)
    {
        Push(num%8);
        num/=8;
    }
     cout<<"转换为八进制:";
     GetAll();
  }
} 

 

3、回文是指正读反读均相同的字符序列,如“acdca”、“dceecd”均是回文,但“book”不是回文。利用1中的基本算法,试写一个算法判定给定的字符串是否为回文。(提示:将一半字符入栈,依次弹出与另一半逐个比较)//判s串是否为回文,是则返回1,否则返回0;

int SeqStack::HuiWen(char *s)
{
    int i,j;
    for(i=0;s[i]!='\0';i++);
    for(j=0;j<(i-1)/2;j++)
    {
        Push(s[j]);
    }
    char ch= Pop();
    if(s[j]==ch)
    {
        for(int k=j;k<i-1;i++)
        {
            if(s[k]!=Pop())
                return 0;
        }
        return 1;
    }

    else if(s[j+1]==ch)
    {
        for(int k=j+2;k<i-1;k++)
        {
            if(s[k]!=Pop())
                return 0;
        }
        return 1;

     }
     else
        return 0;
}
int main()
{
    SeqStack stack1335(10);
    char b[7]={'a','b','s','c','s','b','a'};
cout<<"给定字符串:"<<b<<"是否是回文?(1-是/2-否)"<<stack1335.HuiWen(b)<<endl;
}

 

4、实现栈的链式操作算法。

#include<stdlib.h>
#include<iostream>
using namespace std;
template<class T>
class LinStack;
template <class T>
class StackNode
{
    friend class LinStack<T>;
private:
    T data;
    StackNode<T> *next;
public:
    StackNode(StackNode<T> *ptrNext=NULL)
    {next=ptrNext;}
    StackNode(const T& item,StackNode<T> *ptrNext=NULL)
    {data=item;next=ptrNext;}
    ~StackNode(){}
};
template<class T>
class LinStack
{
private:
    StackNode<T>*head;
    int size;
public:
    LinStack(void);                           //构造函数
    ~LinStack(void);                          //析构函数
    void Push(const T& item);           //入栈
    T Pop(void);                                   //出栈
    T GetTop(void) const;                  //取栈顶元素
    int NotEmpty(void) const;             //堆栈非空否
};
template <class T>
LinStack <T>::LinStack()                    //构造函数
{
    head=new StackNode <T>;                 //头指针指向头结点
    size=0;                                 //size的初值为0
}
template <class T>
LinStack <T>::~LinStack(void)               //析构函数
//释放所有动态申请的结点空间
{
    StackNode <T> *p,*q;
    p=head;                                 //p指向头结点
    while(p!=NULL)                          //循环释放结点空间
    {
        q=p;
        p=p->next;
        delete q;
    }
}
template <class T>
int LinStack <T>::NotEmpty(void) const      //堆栈非空否
{
    if(size!=0)
        return 1;
    else
        return 0;
}
template <class T>
void LinStack <T>::Push(const T& item)      //入栈
{
    //新结点newNode的data域值为item,next域值为head->next
    StackNode <T> *newNode=new StackNode <T> (item,head->next);
    head->next=newNode;                    //新结点插入栈顶
    size++;                                //元素个数加1
}
template <class T>
T LinStack <T>::Pop(void)                  //出栈
{   if(size==0)
    {
        cout<<"堆栈已空无元素可删!"<<endl;
        exit(0);
    }
    StackNode <T> *p=head->next;       //p指向栈顶元素结点
    T data=p->data;
    head->next=head->next->next;       //原栈顶元素结点脱链
    delete p;                          //释放原栈顶结点空间
    size--;                            //结点个数减1
    return data;                   //返回原栈顶结点的data域值
}
template <class T>
T LinStack <T>::GetTop(void) const         //取栈顶元素
{
    return head->next->data;
}

测试数据(main函数)

#include <iostream>
#include"LinStack.h"
using namespace std;

int main()
{
    int n[]={1,2,3,4,5,6,7,8,9,0};
    LinStack<int>li;
    cout<<"入栈元素:";
    for(int i=0;i<10;i++)
    {
        cout<<n[i]<<" ";
        li.Push(n[i]);
    }
    cout<<"\n当前栈顶元素:"<<li.GetTop()<<endl;;
    cout<<"是否非空(1-非空,0-空)"<<li.NotEmpty()<<endl;
    cout<<"出栈一个顶部元素:"<<li.Pop()<<endl;;
    cout<<"当前栈顶元素:"<<li.GetTop()<<endl;;
    return 0;
}

 

5、实现后缀表达式求值Eval(postexp e)算法。

#include <iostream>
#include<ctype.h>
#include<stdlib.h>
#include"LinStack.h"
template <class T>
void PostExp(LinStack <T> &s)
{
    char ch;           //ch为char类型变量
    T x,x1,x2;
    cout<<"输入后缀表达式(表达式以#符号结束):";
    while(cin>>ch&&ch!='#')   //循环直到输入为'#'
    {
        if(isdigit(ch))       //ch为数字类型
        {
            cin.putback(ch);  //回退一位
            cin>>x;           //按数值类型重新输入
            s.Push(x);        //x入栈
        }
        else
        {
            x2=s.Pop();       //退栈得操作数
            x1=s.Pop();       //退栈得被操作数
            switch(ch)
            {
            case'+':{x1+=x2;break;}
            case'-':{x1-=x2;break;}
            case'*':{x1*=x2;break;}
            case'/':
                if(x2==0.0)
                {
                    cout<<"除数为0错!";
                    exit(0);
                }
                else
                {
                    x1/=x2;
                    break;
                }
            }
             s.Push(x1);        //运算结果入栈
          }
    }
    cout<<"后缀表达式计算结果为:"<<s.Pop()<<endl;
}
using namespace std;
int main()
{
   
    LinStack<int>li;
   PostExp(li);
}

 

6、实现中缀表达式转换成后缀表达式postfix(expression e)算法

void error()
{
     cout<<"输入有误 退出"<<endl;
     exit(0);
}
template <class T>
int PostFix(LinStack <T> &s)
{
    string a,b;
    char ch;           //ch为char类型变量
    T x1,x2=' ';
    s.Push('#');
    cout<<"输入中缀表达式(表达式以#符号结束):";
    int flag=1;
    while(true)   //循环直到输入为'#'
    {
        if(x2!='#'&&flag==1)
        {
            b+=ch;
            cin>>ch;
        }
        if(!isdigit(ch))       //ch不为数字类型
        {
            x1=s.GetTop();
            x2=ch;
            if(x2==')')
                flag=0;
            if(x1=='+'||x1=='-')
            {
                if(x2=='+'||x2=='-'||x2==')'||x2=='#')
                {
                    a+=s.Pop();
                }
                else if(x2=='*'||x2=='/'||x2=='(')
                    s.Push(x2);
                else
                    error();
            }
             if(x1=='*'||x1=='/')
            {
                if(x2=='+'||x2=='-'||x2==')'||x2=='#'||x2=='*'||x2=='/')
                     a+=s.Pop();
                else if(x2=='(')
                    s.Push(x2);
                else
                    error();
            }
            if(x1=='(')
            {
                if(x2==')')
                {
                    s.Pop();
                    flag=1;
                }

                else if(x2=='+'||x2=='-'||x2=='*'||x2=='/'||x2=='(')
                    s.Push(x2);
                 else
                     error();
            }
             if(x1==')')
            {
                if(x2=='+'||x2=='-'||x2=='*'||x2=='/'||x2==')'||x2=='#')
                    a+=s.Pop();
                 else
                     error();

            }
             if(x1=='#')
            {
                if(x2=='+'||x2=='-'||x2=='*'||x2=='/'||x2=='(')
                {
                    s.Push(x2);
                }
                else if(x2=='#')
                {
                    cout<<"中缀表达式为:"<<b<<"\n后缀表达式为:"<<a<<endl;
                    return 0;
                }
                else
                     error();
            }
        }
        else                    //ch是数字
        {
            a+=ch;
        }
    }
}

测试函数(main函数)

主函数
int main()
{

    LinStack<int>li;
   PostFix(li);
}

 

 

 

posted @ 2019-03-31 01:34  cc123nice  阅读(1116)  评论(0编辑  收藏  举报