DSAA之Stack(二)

1. 简单的stack的实现

#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#define MAXSTACKSIZE 20
#define  handle_error(msg) do{ perror(msg); exit(-1);}while(0);
typedef  int TYPE;

typedef struct stack{
   int stacksize;
   int topofstack;
   TYPE  * arrary;
} STACK;

void destroy_stack(STACK * stack);
TYPE pop(STACK * stack);
int push(TYPE value,STACK * stack);
STACK * creat_stack(int stacksize);

int main(void){
   STACK * ptr;
   ptr=creat_stack(MAXSTACKSIZE);
   TYPE num;
   printf("push :\n");
   scanf("%d",&num);
   if(push(num,ptr) == -1){
        errx(1,"stack full\n");
   }
   printf("pop %d\n",pop(ptr));
   destroy_stack(ptr);
}

STACK * creat_stack(int stacksize){
   STACK * ptr;
   if((ptr=malloc(sizeof(STACK))) == NULL)
      handle_error("malloc");
   ptr->stacksize=stacksize;
   ptr->topofstack=-1;
   if((ptr->arrary=malloc(stacksize*sizeof(TYPE))) == NULL)
      handle_error("malloc");
   return ptr;
}

int push(TYPE value,STACK * stack){
   STACK * ptr;
   if(stack->topofstack== stack->stacksize)
      return -1;
   (stack->arrary)[++stack->topofstack]=value;
   return 0;
}


TYPE pop(STACK * stack){
   STACK * ptr;
   if(stack->topofstack== -1)
      return -1;
   return (stack->arrary)[stack->topofstack--];
}

void destroy_stack(STACK * stack){
   if(stack != NULL){
      free(stack->arrary);
      free(stack);
   }
}

  结果:

[root@localhost ~]# ./3_3    
push :
5
pop 5
[root@localhost ~]# 

2. 前后缀表达式

  具体来首应该分成两步,首先由中缀表达式,编程前缀或者后缀表达式,然后根据前后缀表达式计算相应的结果。
  中缀变前缀表达式的转换算法度娘

  • 首先构造一个运算符栈(也可放置括号),运算符(以括号为分界点)在栈内遵循越往栈顶优先级不降低的原则进行排列。大于或者等于
  • 右至左扫描中缀表达式,从右边第一个字符开始判断:
    • 如果当前字符是数字,则分析到数字串的结尾并将数字串直接输出。
    • 如果是运算符,则比较优先级。如果当前运算符的优先级大于等于栈顶运算符的优先级(当栈顶是括号时,直接入栈),则将运算符直接入栈;否则将栈顶运算符出栈并输出,直到当前运算符的优先级大于等于栈顶运算符的优先级(当栈顶是括号时,直接入栈),再将当前运算符入栈。
      如果是括号,则根据括号的方向进行处理。如果是右括号,则直接入栈;否则,遇左括号前将所有的运算符全部出栈并输出,遇右括号后将左右的两括号一起删除。
  • 重复上述操作(2)直至扫描结束,将栈内剩余运算符全部出栈并输出,再逆缀输出字符串。中缀表达式也就转换为前缀表达式了。

  前缀表达式计算方式:

  • 对前缀表达式求值,要从右至左扫描表达式.
  • 首先从右边第一个字符开始判断,若当前字符是数字则一直到数字串的末尾再记录下来,若为运算符,则将右边离得最近的两个“数字串”作相应运算,然后以此作为一个新的“数字串”并记录下来;
  • 扫描到表达式最左端时扫描结束,最后运算的值即为表达式的值。
      

  中缀变后缀表达式的转换方式度娘

  • 开始扫描(从左向右),数字时,加入后缀表达式;
  • 遇到运算符运算符:
    • 若为 ‘(‘,入栈;
    • 若为 ‘)’,则依次把栈中的的运算符加入后缀表达式中,直到出现’(‘,从栈中删除’(’ ;
    • 若为 除括号外的其他运算符, 当其优先级高于除’(‘以外的栈顶运算符时,直接入栈。否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低的或者遇到了一个左括号为止。
  • 当扫描的中缀表达式结束时,栈中的的所有运算符出栈;

  后缀表达式的计算方法:

  • 建立一个栈S 。从左到右读表达式,如果读到操作数就将它压入栈S中,如果读到n元运算符(即需要参数个数为n的运算符)则取出由栈顶向下的n项按操作数运算,再将运算的结果代替原栈顶的n项,压入栈S中。如果后缀表达式未读完,则重复上面过程,最后输出栈顶的数值则为结束。

猜你喜欢

转载自blog.csdn.net/LoveStackover/article/details/80033802
今日推荐