数据结构基础2:栈

数据结构基础2:栈

求算术表达式有两种方法:

1.运算符优先级法:该方法来自严蔚敏版数据结构,需要设置两个栈,一个操作数栈,一个操作符栈。

2.后缀表达式法:中缀表达式转后缀表达式(逆波兰式)并求值,分为两个过程,每个过程个需要一个栈。

本文采用后缀表达式法求算术表达式:中缀表达式转后缀表达式的思路大体是判断当前运算符是否比上一个运算符优先级高。

如果高则将当前运算符push压入栈中;如果低,则将上一个运算符pop出来,即把前面的运算当成一个整体先列出来。

main.c

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

/* 中缀表达式转后缀表达式(逆波兰式)并求值 */

char optrset[6] = {'+','-','*','/','(',')'};
char cmpset[6][6] = {/*     +     -    *    /    (    ) */
                    /* + */ '<', '<', '>', '>', '>', '<',
                    /* - */ '<', '<', '>', '>', '>', '<',
                    /* * */ '<', '<', '<', '<', '>', '<',
                    /* / */ '<', '<', '<', '<', '>', '<',
                    /* ( */ '>', '>', '>', '>', ' ', '=',
                    /* ) */ ' ', ' ', ' ', ' ', ' ', ' '};

/*求操作符序号*/
          
int OrderOptr(char c)
{
    int i;
    for(i = 0; i < sizeof(optrset); i++) {
        if(c == optrset[i])
            return i;
    }    
}

/* 操作符比较 */

char CmpOptr(char a, char b)
{
    return cmpset[OrderOptr(a)][OrderOptr(b)];
}

/* 判断是否为操作符 */

int IsOptr(char c)
{
    int i;
    for(i = 0; i < sizeof(optrset); i++) {
        if(c == optrset[i])
            return 1;
    }
    return 0;
}

/*运算*/

char CalOptr(char lv, char rv, char optr)
{
    char res_c;
    int l = 0, r = 0, res = 0;
    l = lv - '0';
    r = rv - '0';
    switch(optr) {
        case '+':
            res = l + r;
            break;
        case '-':
            res = l - r;
            break;
        case '*':
            res = l * r;
            break;
        case '/':
            res = l / r;
            break;
        default:
            break;
    }
    
    res_c = res + '0';
    
    return res_c;
}

int main(int argc, char *argv[])
{
    SPtr stack = NULL;
    char str[20] = {'\0'};
    char cstr[2] = " ", dstr[2] = " ";
    char c, d;
    char result;
    char lvalue, rvalue;
    int i = 0;
    
    stack = CreatStack();

    c = getchar();
    cstr[0] = c;
    
    /* 中缀表达式转后缀表达式 */
    
    while(c != '\n') {
        if(!IsOptr(c)) { 
            cstr[0] = c; 
            strcat(str, cstr);
            c = getchar();
        }
        else {
            if(StackEmpty(stack)) {
                result = '>';
            }
            else {
                GetTop(stack, &d);
                result = CmpOptr(d, c);
            }
            switch(result) {
                case '>':
                    Push(stack, c);
                    c = getchar();
                    break;
                case '=':
                    Pop(stack, &d);
                    c = getchar();
                    break;
                case '<':
                    Pop(stack, &d);
                    dstr[0] = d;
                    strcat(str, dstr);
                    break;
                default:
                    break;
            }
        }
    }

    while(!StackEmpty(stack)) {
        Pop(stack, &d);
        dstr[0] = d;
        strcat(str, dstr);
    }

    printf("%s\n", str);
    
    /* 后缀表达式求值 */
    
    while(str[i] != '\0') {
        if(!IsOptr(str[i]))
            Push(stack, str[i]);
        else {
            Pop(stack, &rvalue);
            Pop(stack, &lvalue);
            Push(stack, CalOptr(lvalue, rvalue, str[i]));
        }
        i++;
    }
    
    Pop(stack, &d);
    printf("The result is %c\n", d);
    
    ClearStack(stack);
    DestroyStack(stack);   

    printf("Press enter to continue ...");
    getchar();
    return 0;
}
Stack.c

#include "Stack.h"

SPtr CreatStack()
{
    SPtr sp = malloc(sizeof(struct LinkStack));
    
    if(!sp)
        return NULL;
        
    sp->base = malloc(sizeof(struct SElemType));
    sp->base->next = NULL;
    sp->top = sp->base;
    sp->stacksize = 0;
    
    return sp;
}

int StackEmpty(SPtr sp)
{
    if(!sp)
        return ERROR;
    
    if(sp->stacksize == 0)
        return 1;
    else
        return 0;
}

int StackLength(SPtr sp)
{
    if(!sp)
        return ERROR;
    
    return sp->stacksize;
}

int GetTop(SPtr sp, ElemType *x)
{
    if(!sp)
        return ERROR;
        
    *x = sp->top->next->value;
    
    return OK;
}

int Push(SPtr sp, ElemType x)
{
    SElemPtr pushnode;
    
    if(!sp)
        return ERROR;
        
    sp->top->value = x;
    pushnode = malloc(sizeof(struct SElemType));
    pushnode->next = sp->top;
    sp->top = pushnode;
    sp->stacksize++;
    
    return OK;
}

int Pop(SPtr sp, ElemType *x)
{
    SElemPtr popnode;
    
    if(!sp)
        return ERROR;
        
    if(sp->top == sp->base)
        return ERROR;
        
    popnode = sp->top->next;
    free(sp->top);
    sp->top = popnode;
    *x = sp->top->value;
    sp->stacksize--;
    
    return OK;
}

int StackTraverse(SPtr sp)
{
    int i;
    SElemPtr tmpnode;
    
    if(!sp)
        return ERROR;
        
    tmpnode = sp->top->next;
    for(i = 0; i < sp->stacksize; i++) {
        printf("%c ", tmpnode->value);
        tmpnode = tmpnode->next;
    }
    printf("\n");
    
    return OK;
}

int ClearStack(SPtr sp)
{
    int i;
    SElemPtr tmpnode;
    
    if(!sp)
        return ERROR;
        
    tmpnode = sp->top->next;
    for(i = 0; i < sp->stacksize; i++) {
        tmpnode->value = '\0';
        tmpnode = tmpnode->next;
    }
    sp->top = sp->base;
    sp->stacksize = 0;
    
    return OK;
}

int DestroyStack(SPtr sp)
{
    SElemPtr tmpnode = sp->top, storenode = NULL; 
    
    if(!sp)
        return ERROR;
    
    while(tmpnode != sp->base) {
        storenode = tmpnode->next;
        free(tmpnode);
        tmpnode = storenode;
    }
    
    free(tmpnode);
    free(sp);
    
    return OK;
}
Stack.h

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define ERROR -1
#define OK 0
#define ElemType char

typedef struct SElemType{
    ElemType value;
    struct SElemType *next;
} *SElemPtr;

typedef struct LinkStack{
    SElemPtr base;
    SElemPtr top;
    int stacksize;
} *SPtr;

SPtr CreatStack();

int StackEmpty(SPtr sp);

int StackLength(SPtr sp);

int GetTop(SPtr sp, ElemType *x);

int Push(SPtr sp, ElemType x);

int Pop(SPtr sp, ElemType *x);

int StackTraverse(SPtr sp);

int ClearStack(SPtr sp);

int DestroyStack(SPtr sp);




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值