刁肥宅手笔:纯C语言利用链栈实现从后缀表达式Array中顺序输入表达式并求值

       链栈+后缀表达式求值算法,借用我自己上次C语言写的链栈,详细实现代码如下:

       头文件C_Stack.h:

/*C_Stack.h*/

#ifndef C_STACK_H_INCLUDED
#define C_STACK_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
#include <math.h>
#include <time.h>
#include <windows.h>

typedef struct Stack
{
    int Data;
    struct Stack *Next;
}LStack,*PStack;

typedef struct Position
{
    struct Stack *PTop;
    struct Stack *PBattom;
}LPosition,*PPosition;

PPosition InitiateStack(PPosition P);/*初始化栈*/
bool Push(PPosition P,int Value);/*压栈*/
bool Pop(PPosition P,int *Tmp);/*弹栈*/
int Top(PPosition P);/*返回栈顶元素*/
void Display(PPosition P);
void ClearStack(PPosition P);/*清空栈*/
bool EmptyStack(PPosition P);/*判断栈是否为空*/
int StackSize(PPosition P);/*求栈所含元素的多少*/


#endif // C_STACK_H_INCLUDED

       源代码C_Stack.c:

/*C_Stack.c*/

#include "C_Stack.h"

PPosition InitiateStack(PPosition P)
{
    P->PTop = (struct Stack*)malloc(sizeof(struct Stack));/*相当于申请一个新结点*/
    if(!(P->PTop))/*申请不成功。养成良好的习惯,最好预先判断;万一哪天一个不小心内存泄漏了,哦嚯!*/
        /*return false;*/
    {
        printf("Initiate failed.\n");
        exit(EXIT_FAILURE);
    }
    P->PBattom = P->PTop;/*栈底指向栈顶*/
	/*
	上面这句话我原来写作:
	P->PTop = P->PBattom;
	查了很长时间才发现问题是:
	很丢人,没有初始化的指针就拿来赋值
	*/
    P->PTop->Next = NULL;/*栈顶指针置为空*/
    /*return true;初始化成功*/
	return P;
}

bool Push(PPosition P,int value)
{
    LStack *PNew = (LStack *)malloc(sizeof(LStack));/*相当于申请一个新结点*/
    if(!PNew)/*申请不成功,压栈失败。养成良好的习惯,最好预先判断;万一哪天一个不小心内存泄漏了,哦嚯!*/
        return false;
    PNew->Data = value;/*数值赋給值域*/
    PNew->Next = P->PTop;/*新结点的指针域指向栈顶*/
    P->PTop = PNew;/*新结点成为新的栈顶*/
    return true;/*压栈成功*/
}

bool Pop(PPosition P,int *Tmp)
{
    /*LStack *PTmp = NULL;申请一个新结点,赋值为空*/
    LPosition *LPTmp = (LPosition *)malloc(sizeof(LPosition));/*开辟一段空间給新结点*/
    if(P->PTop->Next == NULL)/*栈顶指针为空说明栈为空*/
        return false;/*弹栈失败*/
    LPTmp = P;/*为什么创建这个临时结点,刁肥宅自己也不清楚,习惯吧*/
    *Tmp = LPTmp->PTop->Data;
    LPTmp->PTop = LPTmp->PTop->Next;/*栈顶的下一栈元素的指针指向栈顶*/
    free(P);/*弹栈后释放空间*/
    return true;/*弹栈成功*/
}

int Top(PPosition P)
{
    LStack *PTmp = P->PTop;/*新建栈指针指向栈顶*/
    /*printf("%d\n",PTmp->Data);*/
    return PTmp->Data;   /*返回栈顶元素 */
}

void Display(PPosition P)
{
    LStack *Tmp = P->PTop;/*新建栈指针指向栈顶*/
    int Line = 0;/*统计已结点个数*/
    while(Tmp->Next != NULL)/*当栈顶指针不为空时*/
    {
        printf("%-6d",Tmp->Data);/*打印栈顶元素*/
        Line ++;
        if(Line % 10 == 0)
            printf("\n");/*每行打印10个元素*/
        Tmp = Tmp->Next;/*使栈顶的下一栈元素的指针指向栈顶*/
    }
}

void ClearStack(PPosition P)
{
    LPosition *PTmp = (LPosition *)malloc(sizeof(LPosition));/*创建临时位置指针*/
    while(P->PTop->Next != NULL)/*当栈顶指针不为空时*/
    {
        PTmp = P;/*栈顶位置指针赋給临时位置指针*/
        P->PTop = P->PTop->Next;/*使栈顶的下一栈元素的指针指向栈顶*/
        free(P);/*释放当前栈顶元素的空间*/
    }
}

bool EmptyStack(PPosition P)
{
    return P->PTop->Next == NULL;/*当栈为空时,这句话为真,函数返回true;
    当栈非空时,这句话为假,函数返回false*/
}

int StackSize(PPosition P)
{
    LPosition *PTmp = (LPosition *)malloc(sizeof(LPosition));/*创建临时位置指针*/
	//LStack *STmp = P->PTop;
	PTmp = P;/*栈顶指针赋給临时位置指针*/
    int ID = 0;/*初始化计数变量为0*/
    while(PTmp->PTop->Next != NULL)/*当现在的栈顶元素指针不为空时,执行循环体*/
    {

        PTmp->PTop = PTmp->PTop->Next;/*使栈顶的下一栈元素的指针指向栈顶*/
        ID ++;/*计数加一*/
    }
    return ID;/*返回栈元素的个数*/
}

       源代码test.c:

/*test.c*/

#include "C_Stack.h"

bool DoOperator(PPosition P,char Operator);

int main()
{
    LPosition *P = (LPosition *)malloc(sizeof(LPosition));
    /*上面这句话直接写成:
    LPosition *P = NULL;
    会报错,为什么?指针置空,而后指向初始化后栈的首地址,不对吗?
    */
    P = InitiateStack(P);
    char Array[] = "5964-*+93/-#";
    int i = 0,Ans = 0;
    printf("所计算的中缀表达式为:%s\n",Array);
    char Ch = Array[i ++];
    while(Ch != '#')
    {
        if(Ch >= '0' && Ch <= '9')
            if( Push( P,(int)(Ch - 48) ) )
                ;
        else if(Ch == '+' || Ch == '-' || Ch == '*' || Ch == '/')
        {
            if(!DoOperator(P,Ch))
            {
                printf("运算出错!\n");
                exit(EXIT_FAILURE);
            }
        }
        else
        {
            printf("键入了非法字符,请重新输入!\n");
            exit(EXIT_FAILURE);
        }
        Ch = Array[i ++];
    }
    Ans = Top(P);
    printf("Ans = %d.\n栈中内容为:\n",Ans);
    Display(P);
    ClearStack(P);
    return 0;
}

bool DoOperator(PPosition P,char Operator)
{
    int Left = -1,Rigth = -1;
    if(EmptyStack(P))
    {
        printf("缺少右操作数\n");
        return false;
    }
    /*rigth = Top(P);*/
    if(Pop(P,&Rigth))
        ;
    else
    {
        printf("缺少左操作数\n");
        return false;
    }

    if(Pop(P,&Left))
        ;
    else
    {
        printf("缺少左操作数\n");
        return false;
    }

    switch(Operator)
    {
    case '+':
        if(Push(P,Left + Rigth))
            ;
        break;
    case '-':
        if(Push(P,Left - Rigth))
            ;
        break;
    case '*':
        if(Push(P,Left * Rigth))
            ;
        break;
    case '/':
        if(fabs ( (double) Rigth ) )
        {
            printf("Divided by 0.\n");
            return false;
        }
        else
        {
            if(Push(P,Left / Rigth))
                ;
        }
        break;
    default:
        return false;
    }
    return true;
}

       代码成功编译后的运行结果如图所示: 

程序运行结果图示

猜你喜欢

转载自blog.csdn.net/u25th_engineer/article/details/81487775