《数据结构实战》将后缀表达式变成表达式树------二叉树的应用

10 篇文章 0 订阅
2 篇文章 0 订阅

编译原理中对于表达式的管理,前面已经有如何将中缀表达式转为后缀表达式算法了,原理同计算后缀表达式同理,为简单起见,操作符都是简单的二元表达式操作符。因此遇到操作数就形成一个叶子节点,并压栈,遇到操作符,则从栈中取两个节点,形成一颗新的树,并进行压栈。最后从栈中取出的为最终的表达式树。

代码如下:

// 由后缀表达式转换为表达式树

#include <iostream>
#include <stack>
#include <vector>
#include <algorithm>

struct TreeNode
{
	char cOperator;
	int  nData;
	TreeNode* lTree;
	TreeNode* rTree;
	TreeNode()
	{
		cOperator = 0;
		nData = 0;
		lTree = NULL;
		rTree = NULL;
	}
};

std::vector<char> g_vectOperators;

void InitOperators() // 加载操作符
{
	char* strOperators = { "+-*/" };
	for (int i = 0; i < strlen(strOperators); i++)
		g_vectOperators.push_back(*(strOperators + i));
}

TreeNode* EndExpressToTree(char* strExpress) // 后缀表达式转换为表达式树
{
	if (*strExpress == 0)
		return NULL;
	std::stack<TreeNode*> stackExpressNode;
	while (*strExpress != 0)
	{
		auto iter = std::find_if(g_vectOperators.begin(), g_vectOperators.end(), [=](char cOperator) { return cOperator == *strExpress; });
		if (iter != g_vectOperators.end()) // 出栈
		{
			TreeNode* pNode = new TreeNode;
			TreeNode* pTemp = stackExpressNode.top();
			pNode->rTree = pTemp;
			stackExpressNode.pop();
			pTemp = stackExpressNode.top();
			pNode->lTree = pTemp;
			stackExpressNode.pop();
			pNode->cOperator = *strExpress;
			// 新节点压栈
			stackExpressNode.push(pNode);
		}
		else // 是操作数
		{
			TreeNode* pNode = new TreeNode;
			pNode->nData = *strExpress - 48;
			stackExpressNode.push(pNode);
		}
		strExpress++;
	}
	if (stackExpressNode.empty())
		return NULL;
	else
	{
		TreeNode* pNode = stackExpressNode.top();
		stackExpressNode.pop();
		return pNode;
	}
}

void DeleteNode(TreeNode*& pNode)
{
	if (!pNode)
		return;
	DeleteNode(pNode->lTree);
	DeleteNode(pNode->rTree);
	delete pNode;
	pNode = NULL;
}

int main()
{
	InitOperators();
	TreeNode* pNode = EndExpressToTree("12+345+**");
	DeleteNode(pNode);
	return 0;
}


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值