C语言数据结构之利用栈将中缀表达式转换为后缀表达式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a1135004584/article/details/79376637

C语言数据结构之利用栈将中缀表达式转换为后缀表达式

方法:利用栈的特性来解析中缀表达式,最后输出后缀表达式

       具体:    如果是数字则输出

                 如果是'('入栈

                 如果是')'将'('到')'的内容输出

                 如果是'+' '-',如果栈为空则入栈,如果不空将栈里面的内容输出或者输出到'('

                     然后将最后一个和当前字符入栈

                 如果是 '*' '/'则入栈

                 循环上述过程直到为'#'结尾符为止


实现图片:


Stack.h

#ifndef _STACK_H_
#define _STACK_H_

#include <stdbool.h>
#define STACK_INIT_SIZE 100 //栈控件初始化大小
#define STACK_INCREMENT 10 //栈控件增量

typedef struct{
    void * base;//栈底
    void * top;//栈顶
    int stackSize;//当前已经分配的存储空间
    int elementLength;
}SqStack;

typedef enum{
    FAILED,SUCCESS
}Status;

Status initStack(SqStack * pStack,int elength);

void destroyStack(SqStack * pStack);
void clearStack(SqStack * pStack);//将栈置空
bool stackIsEmpty(SqStack * pStack);
int stackLength(const SqStack * pStack);
void * getTop(SqStack * pStack);
void push(SqStack * pStack,void *data);//压栈
void pop(SqStack * pStack,void *data);//出栈,若不空删除栈顶元素并将其值返回

void * get(SqStack * pStack,int i);//获取栈的第i个位置的元素

/**
 * 输出栈中每个元素,如果direction为正则从头到尾输出,反之从尾到头输出.
 * @param pStack
 * @param pfun
 * @param direction
 */
void stackTraverse(SqStack * pStack,void(*pfun)(void *),int direction);

#endif


Stack.c

#include <malloc.h>
#include <memory.h>
#include <assert.h>
#include "Stack.h"

Status initStack(SqStack * pStack,int elength)
{

    pStack->base = malloc((size_t) (elength * STACK_INIT_SIZE));
    if(!pStack->base)//如果分配内存失败
        return FAILED;

    pStack->elementLength = elength;
    pStack->top = pStack->base;
    pStack->stackSize = STACK_INIT_SIZE;

    return SUCCESS;
}

void destroyStack(SqStack * pStack)
{
    if(pStack)
    {
        free(pStack->base);
        pStack->base = NULL;
        pStack->top = NULL;
        pStack->stackSize = 0;
    }

}

void clearStack(SqStack * pStack)//将栈置空
{
    if(pStack)
        pStack->top = pStack->base;
}

bool stackIsEmpty(SqStack * pStack)
{
    if(pStack)
    {
        if(pStack->top == pStack->base)
            return true;
        else
            return false;
    }

    return false;
}

/**
 * 返回栈当前长度
 * 用栈顶减去栈底除以单个元素大小即可.
 * @param pStack
 * @return
 */
int stackLength(const SqStack * pStack)
{
    return (int) (pStack->top - pStack->base)/pStack->elementLength;
}

void * getTop(SqStack * pStack)
{
    if(pStack->top == pStack->base)
        return NULL;
    else
        return pStack->top;
}

void push(SqStack * pStack,void *data)//压栈
{

    if((pStack->top - pStack->base)/pStack->elementLength >= pStack->stackSize)
    {
        pStack->base =
                realloc(pStack->base,
                        (size_t) ((pStack->stackSize + STACK_INCREMENT)*pStack->elementLength));

        assert(pStack->base != NULL);
        pStack->top = pStack->base+pStack->stackSize*pStack->elementLength;
        pStack->stackSize += STACK_INCREMENT;
    }
    memcpy(pStack->top, data, (size_t) pStack->elementLength);

    pStack->top = pStack->top+pStack->elementLength;
}

void pop(SqStack * pStack,void *data)//出栈,若不空删除栈顶元素并将其值返回
{
    if(pStack->top != pStack->base)
    {
        pStack->top -= pStack->elementLength;

        if(data)
            memcpy(data,pStack->top,(size_t)pStack->elementLength);
    }
}


void * get(SqStack * pStack,int i)//获取栈的第i个位置的元素
{
    void * pn = NULL;

    if(stackLength(pStack) != 0)
        pn = &pStack->base[i];

    return pn;
}


/**
 *
 * @param pStack
 * @param pfun
 * @param direction 遍历方向
 * @param isHex 是否是16进制
 */
void stackTraverse(SqStack * pStack,void(*pfun)(void *),int direction)
{
    void * pd = NULL;
    if(direction > 0)
    {
        pd = pStack->base;

        while(pd < pStack->top)
        {
            pfun(pd);
            pd += pStack->elementLength;
        }
    }else{
        pd = pStack->top;

        while(pd > pStack->base)
        {
            pd -= pStack->elementLength;
            pfun(pd);
        }
    }

}


main3.c


#include <stdio.h>
#include <ctype.h>
#include "Stack.h"

int main(void)
{
    SqStack stack;
    initStack(&stack,sizeof(char));

    printf("请输入中缀表达式:");

    char c;
    char temp;
    scanf("%c",&c);

    //1+(1-2*1-2)-5/2
    //1 1 2 1 * - 2 - 5 2 / - +
    while(c != '#')
    {
        if(isdigit(c))
        {
            printf("%c ",c);
        }else if(c == '(')
        {
            push(&stack,&c);
        }else if(c == ')')
        {
            pop(&stack,&temp);
            while(temp != '(')
            {
                printf("%c ",temp);
                pop(&stack,&temp);
            }
        }else if(c == '+' || c == '-')
        {
            if(stackIsEmpty(&stack))
            {
                push(&stack,&c);
            }else{
                pop(&stack,&temp);

                while(!stackIsEmpty(&stack) && temp != '(')
                {
                    printf("%c ",temp);
                    pop(&stack,&temp);
                }
                push(&stack,&temp);
                push(&stack,&c);
            }


        }else if(c == '*' || c == '/')
        {
            push(&stack,&c);
        }

        scanf("%c",&c);
    }

    do
    {
        pop(&stack,&c);
        printf("%c ",c);
    }while(!stackIsEmpty(&stack));
    printf("\n");
    return 0;
}



猜你喜欢

转载自blog.csdn.net/a1135004584/article/details/79376637