栈内链表&用后缀完成计算器功能

正常的表达式         逆波兰表达式

 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;
}

猜你喜欢

转载自blog.csdn.net/GX0401/article/details/81515539