中缀转后缀,后缀求值,后缀构造表达式树

这三种算法都借助栈,中缀转后缀是符号入栈,其他是数值入栈。

中缀转后缀思路:当遇到操作符的时候,放入栈中。栈代表挂起的操作符。遇到左括号时入栈,如果见到右括号,就将栈元素弹出,直到遇到左括号,弹出但不输出。

当遇到其他符号(‘+’, ‘*’, ‘(’),则从栈中弹出栈元素直到发现优先级更低的元素为止。‘(’优先级最高,除非遇到')',否则不出栈。之后当从战中弹出这些元素后,将当前元素入栈。

void zhongtohou(char *exp, char *houexp)
{
    char *p;
	char *pb = houexp;
	stack stk;
	init_stack(&stk);

	for (p = exp; *p != '\0'; p++)
	{
		char c;
		switch (*p)
		{
		case '+':
        case '-':
		    while (!empty(&stk))
			{
                c = top(&stk);
			    if (c == '*' || c == '+' || c == '-' || c == '/')
				{
					pop(&stk);
					printf("%c ", c);
					*pb++ = c;
				}
				else
					break;
			} 
			push(&stk, *p);
			break;
		case ')':
		    while (!empty(&stk))
			{
				c = top(&stk);
				if (c != '(')
				{
					printf("%c ", c);
					*pb++ = c;
					pop(&stk);
				}
				else
					break;
			}
			pop(&stk);
			if (c != '(')
				printf("小括号匹配错误\n");
		    break;
		case '*':
		case '(':
		case '/':
			push(&stk, *p);
			break;
		default:
			if (isalnum(*p))
			{
				printf("%c ", *p);
				*pb++ = *p;
			}
			else
				printf("wrong char\n");
			break;
		}
	}
	while (!empty(&stk))
	{
		printf("%c ", top(&stk));
		*pb++ = top(&stk);
		pop(&stk);
	}
	printf("\n");
}

后缀求值与后缀构造表达式树的思路相似,都是遇到元素入栈,遇到操作符,出栈栈顶两个元素,求值是计算值,并将计算后的值入栈,而表达式树是在构造一个新的符号节点,并将这两个元素作为左右孩子,然后将这个子树入栈,最后变成一棵树。

具体思路:

后缀表达式求值:当遇到一个数时,压入栈中,在遇到一个操作符时就作用于从该栈弹出的两个数上,在将所得结果入栈,最后栈中元素即为表达式值。

void exp_value(char *exp)
{
    stack stk;
	init_stack(&stk);

	int a, b, val;
	char *p = exp;
	while (*p != '\0')
	{
		if (isdigit(*p))
			push(&stk, *p);
		else if (*p == '+' || *p == '-' || *p == '*' || *p == '/')
		{
			a = pop(&stk)-'0';
			b = pop(&stk)-'0';
			printf("%d %d\n", a, b);
			switch (*p)
			{
			case '+':
                val = a+b;
				break;
			case '-':
				val = a-b;
				break;
			case '*':
				val = a*b;
				break;
			case '/':
				val = a/b;
				break;
			default:
				break;
			}
			push(&stk, val+'0');
		}
		p++;
	}
	printf("表达式的值是: %d\n", val);
}

后缀表达式构造表达式树:将后缀表达式一个一个读入字符。如果是数,就建立一个单节点树并将它推入栈中。如果符号是操作符,则从栈中弹出两棵树T1,T2,并形成一棵新的树,该树的跟就是操作符,左右孩子分别是T1,T2.然后将这棵新树的指针入栈。

template <typename Object>
struct BinaryNode
{
	Object element;
	BinaryNode<Object> *left;
	BinaryNode<Object> *right;
};

typedef struct BinaryNode<char> Node;
typedef struct BinaryNode<char>* pNode;

pNode houtoexp(char *exp)
{
	char *p = exp;

	stack<pNode> stk;
	pNode bnode;

	while (*p != '\0')
	{
		 //如果是数字或字母,构造节点,进栈
		 if (isalnum(*p))
		 {
             bnode = new Node;
		     bnode->element = *p;
		     bnode->left = bnode->right = NULL;
			 stk.push(bnode);
		 }
		 else
		 {
			 pNode lnode = stk.top();
			 stk.pop();
			 pNode rnode = stk.top();
			 stk.pop();

			 bnode = new Node;
			 bnode->element = *p;
			 bnode->left = rnode;
			 bnode->right = lnode;
			 stk.push(bnode);
		 }
		 p++;
	}
	return bnode;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值