栈的应用_中缀表达式转后缀表达式

中缀表达式就是我们习惯的表达式比如说1+2*3,后缀表达式是计算机习惯的表达式。
1+2*3转成后缀表达式后:123*+

中缀转后缀算法:

- 遍历中缀表达式中的数字和符号:
- 对于符号:
- 左括号:进栈
- 若栈顶符号优先级低:此符号进栈(默认栈顶若是左括号,左括号优先级最低)

  • 若栈顶符号优先级不低:将栈顶符号弹出并输出,之后进栈

  • 右括号:将栈顶符号弹出并输出,直到匹配左括号遍历结束:将栈中的所有符号弹出并输出

这里写图片描述
数字直接输出:———————————结果:8

这里写图片描述
运算符要先判断优先级,但现在栈为空直接将它进行压栈

这里写图片描述
直接将左括号压栈

这里写图片描述
数字直接输出———————-结果:83

这里写图片描述
碰到运算符将他与当前栈顶比较,括号优先级最低所以-进栈

这里写图片描述
输出—————结果:831

这里写图片描述
碰到右括号将栈顶符号弹出并输出,直到匹配左括号 结果:831-
(括号会抵消掉)

这里写图片描述
乘号优先级比加高,*进栈

这里写图片描述
输出——————–结果:831-5

这里写图片描述
此时以指向 \0 结束符将栈里的元素逐个弹出,结果:831-5*+

.h


//链式栈的节点
typedef struct LINKNODE
{
    struct LINKNODE*next;
}LinkNode;

//链式栈
typedef struct LINKSTACK
{
    LinkNode head;
    int size;

}LinkStack;


class linkstack
{
public:
    linkstack();
    ~linkstack();
public:
    LinkStack* Stack;

public:
    //入栈
    void push_back(LinkStack* stack,LinkNode* data);
    //出栈
    void pop_back(LinkStack* stack);
    //返回栈顶元素
    LinkNode* Top_LinkStack(LinkStack* stack);
    //返回栈元素的个数
    int Size_LinkStack(LinkStack* stack);
    //清空栈
    void Clear_LinkStack(LinkStack* stack);


};

.cpp


linkstack::linkstack()
{
    Stack = new LinkStack;

    Stack->head.next = NULL;
    Stack->size = 0;
}

linkstack::~linkstack()
{
    if (Stack == NULL)
    {
        return;
    }

    delete Stack;


}

//入栈
void linkstack::push_back(LinkStack* stack, LinkNode* data)
{
    if (stack == NULL || data == NULL)
    {
        return;
    }

    data->next = stack->head.next;
    stack->head.next = data;
    stack->size++;
}

//出栈
void linkstack::pop_back(LinkStack* stack)
{
    if (stack == NULL || stack->size == 0)
    {
        return;
    }

    LinkNode* pNext = stack->head.next;
    stack->head.next = pNext->next;

    stack->size--;
}

//返回栈顶元素
LinkNode* linkstack::Top_LinkStack(LinkStack* stack)
{
    if (stack == NULL || stack->size == 0)
    {
        return NULL;
    }

    return stack->head.next;
}

//返回栈元素的个数
int linkstack::Size_LinkStack(LinkStack* stack)
{
    if (stack == NULL )
    {
        return -1;
    }

    return stack->size;
}

//清空栈
void linkstack::Clear_LinkStack(LinkStack* stack)
{
    if (stack == NULL || stack->size == 0)
    {
        return;
    }

    stack->head.next = NULL;
    stack->size = 0;
}

main.cpp

linkstack* s = new linkstack();

//判断是否是数字
int IsNumber(char c)
{
    return c >= '0' && c <= '9';
}

//判断是否为左括号
int IsLeft(char c)
{
    return c == '(';
}

//判断是否为右括号
int IsRight(char c)
{
    return c == ')';
}

//判断是否为运算符
int IsOperator(char c)
{
    return c == '+' || c == '-' || c == '*' || c == '/';
}



//返回运算符优先级
int GetPriority(char c)
{
    if (c == '*' || c == '/')
    {
        return 2;
    }

    if (c == '+' || c == '-')
    {
        return 1;
    }


    return 0;
}

typedef struct MYCHAR
{
    LinkNode node;
    char* p;

}MyChar;

//数字操作
void NuberOperate(char* p)
{
    cout << *p;
}

//创建MyChar
MyChar* CreateMyChar(char* p)
{
    MyChar* mychar = new MyChar;
    mychar->p = p;

    return mychar;
}

//左括号操作
void LeftOperate(LinkStack* stack,char* p)
{
    s->push_back(stack,(LinkNode*)CreateMyChar(p));
}

//右括号操作
void RinghtOperate(LinkStack* stack)
{


    //判断栈中有没有元素
    while (s->Size_LinkStack(s->Stack) >0)
    {
        MyChar* mychar = (MyChar*)s->Top_LinkStack(s->Stack);

        //如果匹配到左括号
        if (IsLeft(*mychar->p))
        {
            s->pop_back(s->Stack);
            break;
        }

        //输出
        cout << *mychar->p;
        //弹出
        s->pop_back(stack);
        //释放内存
        delete mychar;

    }
}

//运算符操作
void OperatorOperator(LinkStack* stack,char* p)
{
    //先取出栈顶元素
    MyChar* mychar = (MyChar*)s->Top_LinkStack(stack);

    if (mychar == NULL)
    {
        s->push_back(stack, (LinkNode*)CreateMyChar(p));
        return;
    }

    //如果栈顶优先级低于当前字符优先级 直接入栈
    if (GetPriority(*mychar->p) < GetPriority(*p))
    {
        s->push_back(stack,(LinkNode*)CreateMyChar(p));
        return;
    }
    else //如果栈顶优先级不低
    {
        while (s->Size_LinkStack(stack) >0)
        {
            MyChar* mychar2 = (MyChar*)s->Top_LinkStack(stack);

            //如果优先级低 当前符号入栈
            if (GetPriority(*mychar2->p) < GetPriority(*p))
            {
                s->push_back(stack,(LinkNode*)CreateMyChar(p));
                break;
            }


            //输出
            cout <<*mychar2->p;
            //弹出
            s->pop_back(stack);
            //释放内存
            delete mychar2;



        }


    }


}

int main()
{
    char* str = "8+(3-1)*5";
    char* p = str;

    while (*p != '\0')
    {

        //如果是数字直接输出
        if (IsNumber(*p))
        {
            NuberOperate(p);
            goto go;
        }

        //如果是左括号直接进栈
        if (IsLeft(*p))
        {
            LeftOperate(s->Stack, p);
            goto go;
        }

        //如果是右括号
        if (IsRight(*p))
        {
            RinghtOperate(s->Stack);
            goto go;
        }

        //如果是运算符
        if (IsOperator(*p))
        {
            OperatorOperator(s->Stack,p);
            goto go;
        }

        go:
        p++;
    }

    while (s->Size_LinkStack(s->Stack) >0)
    {
        MyChar* mychar = (MyChar*)s->Top_LinkStack(s->Stack);
        cout << *mychar->p;
        s->pop_back(s->Stack);
        delete mychar;
    }


    delete s;
    return 0;
}

结果:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值