栈的应用之简易逆波兰计算器

时间:2023-01-09 10:45:39

写的很简单用链表栈实现的,没加注释。只实现了基本的加减乘除四则运算,其它运算符可自行添加。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define N 50
typedef double Type;
typedef struct StackLink
{
    Type data;
    struct StackLink *pNext;
}StackLink, *StackPtr;
// 入栈操作
void Push(StackPtr *phead, Type m)
{
    if (*phead == NULL)
    {
        StackPtr NewNode = (StackPtr)malloc(sizeof(StackLink));
        NewNode->data = m;
        NewNode->pNext = NULL;
        *phead = NewNode;
    }
    else
    {
        StackPtr p = *phead;
        while (p->pNext != NULL)
        {
            p = p->pNext;
        }
        StackPtr NewNode = (StackPtr)malloc(sizeof(StackLink));
        NewNode->data = m;
        NewNode->pNext = NULL;
        p->pNext=NewNode;
    }
}
// 出栈操作 边出栈边释放内存
void Pop(StackPtr *phead,Type *T)
{
    if (*phead == NULL)
    {
        printf("栈空无法出栈\n");
        return ;
    }
    else if ((*phead)->pNext == NULL)
    {    
        *T = (*phead)->data;
        free(*phead);
        *phead = NULL;
    }
    else
    {
        StackPtr p,p1;
        p = *phead;
        p1 = NULL;
        while (p->pNext->pNext!= NULL)
        {
            p = p->pNext;
        }
        p1 = p;
        p = p1->pNext;
        *T = p->data;
        free(p);
        p1->pNext = NULL;
    }
}
/* 打印栈中的元素
void PrintStack(StackPtr phead)
{
    if (phead == NULL)
    {
        printf("栈空无法输出所有节点\n");
    }
    else
    {
        StackPtr p = phead;
        while (p != NULL)
        {
            printf("%.3f\n", p->data);
            p = p->pNext;
        }
    }
}
*/
/* 上面Pop出栈操作已将head置空了故不需要再释放内存
void *FreeStack(StackPtr phead)
{
    StackPtr p1, p2;
    p1 = p2 = phead;
    while (p1->pNext!=NULL)
    {
        p2 = p1->pNext;
        p1 = p2->pNext;
        free(p2);
    }
    free(phead);
    return NULL;
}
*/
/*  统计栈中的结点个数
int CountStack(StackPtr phead)
{
    int count = 0;
    if (phead == NULL)
    {
        printf("栈空\n");
    }
    else
    {
        StackPtr p = phead;
        while (p!= NULL)
        {
            count++;
            p = p->pNext;
        }
    }
    return count;
}
*/
// 判断栈是否为空
int IsEMpty(StackPtr phead)
{
    if (phead == NULL)
        return 0;
    return 1;
}
int main()
{
    StackPtr head=NULL;
    int i=0;
    Type A, B;
    char ch,Buffer[N];
    printf("请输入你要计算的表达式以#结束(PS:操作符与操作数之间必须要有空格)\n");
    scanf("%c", &ch);
    while (ch != '#')
    {
        while (isdigit(ch) || ch == '.')
        {
            Buffer[i++] = ch;
            Buffer[i] = '\0';
            if (i >= N)
            {
                printf("抱歉输入的数据太大。。。\n");
                return -1;
            }
            scanf("%c", &ch);
            if (ch == ' ')
            {
                A = atof(Buffer);
                Push(&head, A);
                i = 0;
                break;
            }
        }
        switch (ch)
        {
            case '+':
                Pop(&head,&A);
                Pop(&head,&B);
                Push(&head,B + A);
                break;
            case '-':
                Pop(&head, &A);
                Pop(&head, &B);
                Push(&head,B - A);
                break;
            case '*':
                Pop(&head, &A);
                Pop(&head, &B);
                Push(&head, B * A);
                break;
            case '/':
                Pop(&head, &A);
                Pop(&head, &B);
                if (A == 0)
                {
                    printf("错误 除数为零!\n");
                    return -1;
                }
                else
                    Push(&head,B / A);
                break;
        }
        scanf("%c", &ch);
    }
    Type result;
    if(IsEMpty(head))
    {
        Pop(&head, &result);
        printf("Result=%.3f\n",result);
    }
    printf("\n");
    system("pause");
    return 0;
}

栈的应用之简易逆波兰计算器