链表,数组实现堆栈,表达式计算

本文介绍了使用C++通过数组和链表两种方式实现堆栈,并应用于表达式的中缀转后缀及计算。分别提供了ArrayStack和LinkStack的实现,以及Test和Expression类的详细说明,最后在Main()函数中进行了测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、 结果显示

  1. 堆栈实现测试 Test.h
    在这里插入图片描述
  2. 表达式运算: Expression.h
    在这里插入图片描述
    二、 ArrayStack.h

 #include<iostream>
    using namespace std;
    
    const int Max_size = 128;
    
    template<typename T>
    class ArrayStack
   {
    public:
        ArrayStack()
        {
            count = 0;
            array = new T[Max_size];
        };
        ~ArrayStack()
        {
            if(count == 0)
        {
            delete array;
            cout<<endl;
            cout<<"栈为空析构"<<endl;
        }
        else
        {
            while(count > 0)
                this->pop();
            delete array;
            cout<<endl;
            cout<<"清除栈内元素析构"<<endl;
        }
    };
 	T pop()    //弹栈
	{
   		 if(count < 0 )
   		 {
    	    cout<<endl;
    	    cout<<"弹栈时:栈内元素数量有误!"<<endl;
   		 }
	    if(count == 0)
  	    {
     	   cout<<endl;
           cout<<"弹栈时:栈为空!"<<endl;
        }
        else
            return array[(count--)-1];
   	 }

    void push(T data)  //推栈
    {
        if(count < 0 )
        {
            cout<<endl;
            cout<<"推栈时:栈内元素数量有误!"<<endl;
        }
        else
            array[(++count)-1] = data;
    }

    int size()   //栈内元素个数
    {
        return count;
    }

    bool isEmpty()   //判断栈内是否为空
    {
        return count == 0?1:0;
    }

    T top()      //返回栈顶元素
    {
        if(count == 0)
            cout<<"栈顶:栈为空栈!!!"<<endl;
        else
            return array[count-1];
    }

    void Show()
    {
        if(count<0)
        {
            cout<<endl;
            cout<<"Show:堆栈内元素个数有误!"<<endl;
        }
        if(count == 0)
        {
            cout<<endl;
            cout<<"Show:堆栈为空!"<<endl;
        }
        else
        {
            int i = count;
            cout<<endl;
            cout<<"Show:堆栈内元素为:"<<"[";
            for(; i>1; i--)
                cout<<array[count-i]<<",";
            cout<<array[count-1];
            cout<<"]"<<endl;
        }
    }
    int count;
    protected:
        T *array;
         };

三、 LinkStack.h

#include<iostream>
using namespace std;

template<typename T>
class LinkStack
{
public:
    int count;

    struct Node
    {
        T data;
        Node *next;
    };

    LinkStack()
    {
        count = 0;
        head = new Node;
        head->next = NULL;
    };
    ~LinkStack()
    {
        if(count == 0)
        {
            delete head;
            cout<<endl;
            cout<<"栈为空析构"<<endl;
        }
        else
        {
            while(count > 0)
            {
                this->pop();
            }
            delete head;
            cout<<endl;
            cout<<"清除栈内元素析构"<<endl;
        }
    };

    T pop()    //弹栈
    {
        if(count < 0 )
        {
            cout<<endl;
            cout<<"栈内元素数量有误!"<<endl;
        }
        if(count == 0)
        {
            cout<<endl;
            cout<<"栈为空!"<<endl;
        }
        else
        {
            Node *p = head;
            int n = count;
            for(int i = 0; i<count; i++)
                p = p->next;
            count--;
            return p->data;
        }
    }

    void push(T data)  //推栈
    {
        if(count < 0 )
        {
            cout<<endl;
            cout<<"栈内元素数量有误!"<<endl;
        }
        if(count >= 0)
        {
            Node *p = head;
            Node *ptemp = new Node;
            for(int i =0; i<count; i++)
                p = p->next;
            ptemp->data = data;
            ptemp->next = p->next;
            p->next = ptemp;
            p = ptemp;
            count++;
        }
    }

    int size()   //栈内元素个数
    {
        return count;
    }

    bool isEmpty()   //判断栈内是否为空
    {
        return count == 0?1:0;
    }

    T top()      //返回栈顶元素
    {
        if(count == 0)
            cout<<"栈为空栈!!!"<<endl;
        else
        {
            Node *p = head;
            for(int i = 0; i<count; i++)
                p = p->next;
            return p->data;
        }
    }

    void Show()
    {
        if(count<0)
        {
            cout<<endl;
            cout<<"堆栈内元素个数有误!"<<endl;
        }
        if(count == 0)
        {
            cout<<endl;
            cout<<"堆栈为空!"<<endl;
        }
        else
        {
            Node *p = head;
            int i = count;
            cout<<endl;
            cout<<"堆栈内元素为:";
            for(int i = 1; i<count+1; i++)
            {
                p = p->next;
                cout<<p->data<<",";
            }
            cout<<endl;
        }
    }
private:

    Node *head;
};

四、Test.h

#include<iostream>
//#include "ArrayStack.h"
#include"LinkStack.h"
using namespace std;

Test()
{
    ArrayStack<char> a1;
    LinkStack<char> l1;
    //a1 = new ArrayStack<T>;
    //l1 = new LinkStack<T>;
    cout<<"栈内元素个数:";
    cout<<"数组:"<<a1.size()<<"!!"<<"链表:"<<l1.size()<<"!!"<<endl;
    cout<<endl;
    cout<<"一、推栈!!!"<<endl;
    cout<<"数组实现>>";
    for(int i=0; i<10; i++)
        a1.push('a'+i);
    cout<<"栈内元素个数:"<<a1.size()<<"。";
    a1.Show();
    cout<<endl;
    cout<<"链表实现>>";
    for(int i=0; i<10; i++)
        l1.push('a'+i);
    cout<<"栈内元素个数:"<<l1.size()<<"。";
    l1.Show();
//************************************************
    cout<<endl;
    cout<<"二、弹栈!!!"<<endl;
    cout<<"数组实现>>";
    int n = a1.size();
    cout<<"弹出栈内后一半元素!"<<"*****"<<"[";
    for(int i=n; i>n/2+1; i--)
        cout<<a1.pop()<<",";
    cout<<a1.pop()<<"]"<<endl;
    cout<<"栈内元素个数为:"<<a1.size()<<"。"<<endl;
    cout<<"链表实现>>";
    int m = l1.size();
    cout<<"弹出栈内后一半元素!"<<"*****"<<">";
    for(int i=m; i>m/2+1; i--)
        cout<<l1.pop()<<",";
    cout<<l1.pop()<<"<"<<endl;
    cout<<"栈内元素个数为:"<<l1.size()<<"。"<<endl;
//************************************************
    cout<<endl;
    cout<<"三、判断栈是否为空!!!"<<endl;
    cout<<"数组实现>>";
    if(!a1.isEmpty())
    {
        cout<<"栈内非空!!";
        a1.Show();
    }
    else
        cout<<"空栈!!!"<<endl;
    cout<<"链表实现>>";
    if(!l1.isEmpty())
    {
        cout<<"栈内非空!!";
        l1.Show();
    }
    else
        cout<<"空栈!!!"<<endl;
//************************************************
    cout<<endl;
    cout<<"四、返回栈顶元素:"<<endl;
    cout<<"数组实现>>";
    cout<<a1.top()<<endl;
    cout<<"链表实现>>";
    cout<<l1.top()<<endl;
    cout<<"栈内元素个数:数组>>"<<a1.size()<<endl;
    cout<<"栈内元素个数:链表>>"<<l1.size()<<endl;
    return 0;
}

五、Expression.h

#include <iostream>
#include"ArrayStack.h"
#include <queue>
#include <string>
#include <sstream>

class Expression
{
public:
    Expression();        //构造函数  输入
    Expression(string str);   //构造函数给定默认算式
    void operator=(string str);   //m_string = str
    double Calculate();
private:
    queue<string> Divide2Item();     //区分数字和操作符 获取为队列
    ArrayStack<string> Change2Postfix();   //中缀转后缀
    int Size();    //计算算式长度
    bool isBacketPair();   //判断括号是否匹配
    bool isNum(char c);          //判断是否为数字

    string m_string;       //输入的算式
};

Expression::Expression()
{
    string exp ;
    cout<<"请输入运算式:";
    cin>>exp;
    this->m_string = exp;
}

Expression::Expression(string str)
{
    this->m_string = str;
}

int Expression::Size()
{
    return m_string.size();
}

bool Expression::isBacketPair()
{
    ArrayStack<char> Backet;
    int n = Size();
    for(int i =0; i < n; i++)
    {
        char c = m_string.at(i);
        switch(c)
        {
        case '(':
            Backet.push(c);
            break;
        case ')':
            if(Backet.isEmpty())
                return false;
            else
                Backet.pop();
            break;
        default:
            break;
        }
    }
    return Backet.isEmpty();
}

bool Expression::isNum(char c)
{
    switch(c)
    {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case '.':
        return true;
        break;
    case '+':
    case '-':
    case '*':
    case '/':
    case '(':
    case ')':
        return false;
        break;
    default:
        return false;
    }
}

void Expression::operator=(string str)
{
    this->m_string = str;
}

queue<string> Expression::Divide2Item()
{
    queue<string> que;
    string str = "";

    if(!isBacketPair())
    {
        cout<<endl;
        cout<<"输入有错,括号配对,请重新输入!!"<<endl;
    }

    for(int i = 0; i < Size(); i++)
    {
        char cc;
        cc = m_string.at(i);
        if(isNum(cc))
        {
            str += m_string.at(i);
            if(i == Size()-1)
                que.push(str);
        }
        else
        {
            if(str.size() != 0)
                que.push(str);
            str = m_string.at(i);
            que.push(str);
            str = "";
        }
    }
    return que;
}

ArrayStack<string> Expression::Change2Postfix()
{
    queue<string> que = Divide2Item();
    ArrayStack<string> OperStack;
    ArrayStack<string> PostStack;
    int LBacktet = 0;
    string str;
    while(!que.empty())
    {
        str = que.front();
        que.pop();
        if(str == " ")
            continue;
        if(str == "(")
        {
            OperStack.push(str);
            LBacktet++;
            continue;
        }

        if(str == ")")
        {
            while(!OperStack.isEmpty()&&OperStack.top() != "(")
                PostStack.push(OperStack.pop());
            if(!OperStack.isEmpty())
            {
                LBacktet--;
                OperStack.pop();
            }
            continue;
        }
        if(str == "+"||str == "-")
        {
            if(OperStack.isEmpty()||OperStack.top() == "(")
                OperStack.push(str);
            else
            {
                while((OperStack.top() =="+"||OperStack.top() =="-"||OperStack.top() =="*"||OperStack.top() =="/")&& !OperStack.isEmpty())
                    PostStack.push(OperStack.pop());
                OperStack.push(str);
            }
            continue;
        }
        if(str == "*" || str == "/")
        {
            if (OperStack.isEmpty() || OperStack.top() == "("  || OperStack.top() == "-" || OperStack.top() == "+")
                OperStack.push(str);
            else
            {
                PostStack.push(OperStack.pop());
                OperStack.push(str);
            }
            continue;
        }
        else
        {
            PostStack.push(str);
            continue;
        }
    }
    while (!OperStack.isEmpty())
    {
        if(OperStack.top() != "(")
            PostStack.push(OperStack.pop());
    }
    while(!PostStack.isEmpty())
        OperStack.push(PostStack.pop());   //倒序  为进行计算时堆栈LIFO
    return OperStack;
}

double Expression::Calculate()
{
    ArrayStack<string> PostStack = Change2Postfix();
    if(PostStack.isEmpty())
        return 0;
    ArrayStack<double> Num;
    string str;
    char ch;
    double num,minu,divi;
    while(!PostStack.isEmpty())
    {
        str = PostStack.pop();
        ch = str[0];
        switch(ch)
        {
        case '*':
            num = Num.pop() * Num.pop();
            Num.push(num);
            break;
        case '+':
            num = Num.pop() + Num.pop();
            Num.push(num);
            break;
        case '-':
            minu = Num.pop();
            num = Num.pop()-minu;
            Num.push(num);
            break;
        case '/':
            if(Num.top() != 0)
            {
                divi = Num.pop();
                num = Num.pop()/divi;
                Num.push(num);
            }
            else
            {
                cout<<endl;
                cout<<"除数为0 ,出错!!"<<endl;
            }
            break;
        default:
            double a;
            istringstream istr(str);
            ostringstream ostr ;
            istr>>a;
            ostr<<a;
            Num.push(a);
            break;
        }
    }
    return Num.top();
}

六、Main()

#include"Expression.h"
#include "Test.h"
int main()
{
      Test();
//    Expression expr;
//    cout<<"计算已经定义号的算式,请随机输入一个数字,点击回车!!"<<endl;
//    Expression expr1;
//    expr1 = "52.1-(2.0*4.2-2)/3.1+3";
//    cout << "输入的算式结果为******************: "<<expr.Calculate()<<endl;
//    cout << "已经定义的算式结果为**************: "<<expr1.Calculate()<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值