正常的表达式 逆波兰表达式
a+b --->a,b,+
a+(b-c) ---> a,b,c,-,+
a+(b-c)*d ---> a,b,c,-,d,*,+
a+d*(b-c)--->a,d,b,c,-,*,+
a=1+3 ---> a,1,3,+,=
它的优势在于只用两种简单操作,入栈和出栈就可以搞定任何普通表达式的运算。其运算方式如下:
如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。
在表达式中的转换规则
操作数 :进栈
操作符 :1)进栈:
空栈
优先级高
栈顶是‘( ’同时表达式不是‘ )’
2)出栈并计算:
表达式符号的优先级不高于栈顶符号
表达式为‘ )’同时栈顶不为‘( ’
表达式‘\0’同时栈不为空
3)出栈但不计算:
表达式为‘ )’同时栈顶为‘( ’
头文件
#ifndef _STACKLINK_H
#define _STACKLINK_H
#define SUCCESS 10000
#define FAILURE 10001
#define TRUE 10002
#define FALSE 10003
#include<stdlib.h>
typedef int elemtype;
struct node //结点的信息
{
elemtype data; //数据域
struct node *next; //指针域
};
typedef struct node Node; //栈的信息
struct stack
{
Node *top; //头指针
int count; //结点个数
};
typedef struct stack Stack;
int Linkinit(Stack **s);
int Linkempty(Stack *s);
int Push(Stack **s, elemtype e);
int Gettop(Stack *s);
int Pop(Stack **s);
int Clear(Stack **s);
int Destory(Stack **s);
#endif
功能函数
#include"linkstack.h"
int Linkinit(Stack **s)
{
if( NULL == s)
{
return FAILURE;
}
(*s) = (Stack *)malloc(sizeof(Stack) * 1 );
if( NULL == *s)
{
return FAILURE;
}
(*s) -> top = NULL;
(*s) -> count = 0;
return SUCCESS;
}
int Linkempty(Stack *s)
{
if( NULL == s)
{
return FAILURE;
}
return( s -> top == NULL ) ? TRUE : FALSE;
}
int Push(Stack **s, elemtype e)
{
if( s == NULL || (*s) == NULL )
{
return FAILURE;
}
Node *p = (Node *)malloc(sizeof(Node));
if( NULL == p)
{
return FAILURE;
}
p->data = e; //哪几个进栈了
p->next = (*s)->top;
(*s)->top = p;
(*s)->count++;
return SUCCESS;
}
int Gettop(Stack *s)
{
if( s == NULL || NULL == s->top)
{
return FAILURE;
}
return s->top->data;
}
int Pop(Stack **s)
{
if( NULL == s || NULL == *s)
{
return FAILURE;
}
Node *p = (*s)->top;
elemtype e = (*s)->top->data;
(*s)->top = (*s)->top->next;
free(p);
(*s)->count--;
return e; //给e赋值,告知哪个出栈了
}
int Clear(Stack **s)
{
if( NULL == s || NULL == *s)
{
return FAILURE;
}
Node *p = (*s)->top;
while(p)
{
(*s)->top = p->next;
free(p);
p = (*s)->top;
(*s)->count--;
}
return SUCCESS;
}
int Destory(Stack **s)
{
if( NULL == s || NULL == *s)
{
return FAILURE;
}
free(*s);
(*s) = NULL;
return SUCCESS;
}
栈内链表基本功能
#include"linkstack.h"
#include<stdio.h>
int main()
{
int ret, i;
Stack *stack;
ret = Linkinit(&stack);
if(ret == SUCCESS)
{
printf("init stack link success!\n");
}
else
{
printf("init stack link failure!\n");
}
ret = Linkempty(stack);
if(ret == TRUE)
{
printf("linkstack is empty!\n");
}
else if(ret == FALSE)
{
printf("linkstack is not empty!\n");
}
else
{
printf("empty : error!\n");
}
for(i = 0; i < 10; i++)
{
ret = Push(&stack, i);
if(ret == FAILURE)
{
printf("push %d failure!\n", i);
}
else
{
printf("push %d success!\n", i);
}
}
ret = Gettop(stack);
if( ret == FAILURE)
{
printf("get top failure!\n");
}
else
{
printf("Top is %d\n", ret);
}
for(i = 0; i < 5; i++)
{
ret = Pop(&stack);
if( FAILURE == ret)
{
printf("pop failure!\n");
}
else
{
printf("Pop %d success!\n", ret);
}
}
ret = Gettop(stack);
if( ret == FAILURE)
{
printf("get top failure!\n");
}
else
{
printf("Top is %d\n", ret);
}
ret = Clear(&stack);
if( ret == SUCCESS)
{
printf("clear Success!\n");
}
else
{
printf("clear Failure!\n");
}
ret = Gettop(stack);
if( ret == FAILURE)
{
printf("get top failure!\n");
}
else
{
printf("Top is %d\n", ret);
}
ret = Destory(&stack);
if( ret == SUCCESS)
{
printf("destory success!\n");
}
else
{
printf("destory failure!\n");
}
for(i = 0; i < 10; i++)
{
ret = Push(&stack, i);
if(ret == FAILURE)
{
printf("push %d failure!\n", i);
}
else
{
printf("push %d success!\n", i);
}
}
return 0;
}
计算机主函数
#include<stdio.h>
#include"linkstack.h"
int Priority(char ch)
{
switch(ch)
{
case '(':
return 3;
case '*':
case '/':
return 2;
case '+':
case '-':
return 1;
default:
return 0;
}
}
int main()
{
Stack *s_opt, *s_num;
char opt[1024] = {0}; //存放表达式
int i = 0, tmp = 0, num1 = 0, num2 = 0;
if( Linkinit(&s_opt) != SUCCESS || Linkinit(&s_num) != SUCCESS )
{
printf("init failure!\n");
}
printf("please input :\n");
scanf("%s", opt);
while( opt[i] != '\0' || Linkempty(s_opt) != TRUE) //表达式没结束 或者 操作符栈不为空
{
if( opt[i] >= '0' && opt[i] <= '9' ) //操作数
{
tmp = tmp * 10 + opt[i] - '0';
i++;
if( opt[i] > '9' || opt[i] < '0') //操作符
{
Push(&s_num, tmp);
tmp = 0;
}
}
else //操作符
{
if( opt[i] == ')' && Gettop(s_opt) == '(' ) //出栈不计算
{
Pop(&s_opt);
i++;
continue;
}
if( Linkempty(s_opt) == TRUE || (Priority( opt[i] ) > Priority(Gettop(s_opt))) || (Gettop(s_opt) == '(' && opt[i] != ')' )) //进栈
{
Push(&s_opt, opt[i]);
i++;
continue;
}
if( (opt[i] == '\0' && Linkempty(s_opt) != TRUE) ||
( opt[i] == ')' && Gettop(s_opt) != '(' ) ||
(Priority(opt[i]) <= Priority(Gettop(s_opt)))) //出栈计算
{
switch(Pop(&s_opt))
{
case '+':
num1 = Pop(&s_num);
num2 = Pop(&s_num);
Push(&s_num, (num1 + num2));
break;
case '-':
num1 = Pop(&s_num);
num2 = Pop(&s_num);
Push(&s_num, (num2 - num1));
break;
case '*':
num1 = Pop(&s_num);
num2 = Pop(&s_num);
Push(&s_num, (num1 * num2));
break;
case '/':
num1 = Pop(&s_num);
num2 = Pop(&s_num);
Push(&s_num, (num2 / num1));
break;
}
}
}
}
printf("%d\n", Gettop(s_num));
return 0;
}