/* 后缀表达式建立二叉树并遍历测试
* 原理:
扫描后缀表达式,遇到操作数时即建立单二叉树节点, 左右指针都为空,放入栈中, 遇到
操作符时也建立单二叉树节点, 但是节点的左右指针需要取栈顶元素,即此时依次从栈顶
出栈的元素分别作为当前扫描节点的右,左子树(注意顺序), 之后也将该节点进栈, 循环
该步骤直到后缀表达式结尾, 此时栈顶元素即为建立好的二叉树的根节点.
可以用二叉树的逆波兰式与原始表达式对比验证, 同时可以打印中序遍历, 得到自然表达式.
后缀表达式测试用例: "ab+cde+**"
*/
#include <stdio.h>
#include <stack>
#include <stdlib.h>
typedef struct _tBINARY_TREE_
{
int value;
_tBINARY_TREE_ *lchild;
_tBINARY_TREE_ *rchild;
}tBINARY_TREE;
static bool is_operator(const char c);
static int priority_com(int operator1, int operator2);
static tBINARY_TREE *suffix_express_create_binary_tree(const char *suffix_express)
{
std::stack<tBINARY_TREE *> operator_stack;
const char *p = suffix_express;
while (*p != '\0')
{
if (!is_operator(*p))
{
tBINARY_TREE *ptree = new tBINARY_TREE;
ptree->value = *p;
ptree->lchild = NULL;
ptree->rchild = NULL;
operator_stack.push(ptree);
}
else
{
tBINARY_TREE *ptree = new tBINARY_TREE;
ptree->value = *p;
ptree->lchild = NULL;
ptree->rchild = NULL;
if (!operator_stack.empty())
{
ptree->rchild = operator_stack.top();
operator_stack.pop();
}
if (!operator_stack.empty())
{
ptree->lchild = operator_stack.top();
operator_stack.pop();
}
if (ptree->lchild == NULL || ptree->rchild == NULL)
{
printf("express is invalid, exit.\n");
exit(-2);
}
operator_stack.push(ptree);
}
++p;
}
if (operator_stack.empty())
{
printf("internal error.\n");
exit(-1);
}
tBINARY_TREE *pRoot = operator_stack.top();
operator_stack.pop();
return pRoot;
}
//递归先序遍历
void pre_order_reserver_tree(tBINARY_TREE *pTree)
{
if (pTree != NULL)
{
printf("%c", pTree->value);
pre_order_reserver_tree(pTree->lchild);
pre_order_reserver_tree(pTree->rchild);
}
return;
}
//递归中序遍历
static void in_order_traverser(tBINARY_TREE *pTree)
{
int flag_l = 0, flag_r = 0;
if (pTree != NULL)
{
int ret;
if (pTree->lchild != NULL) //非叶子节点
{
ret = priority_com(pTree->value, pTree->lchild->value);
if (ret < 0)
{
printf("2. invalid express, exit.\n");
exit(-1);
}
else if (ret == 1) //当前节点的优先级大于左子树, 左子树需要加括号, 防止误解
{
printf("%c", '(');
flag_l = 1;
}
}
in_order_traverser(pTree->lchild);
if (flag_l == 1)
{
printf("%c", ')');
flag_l = 0;
}
printf("%c", pTree->value);
if (pTree->rchild != NULL) //非叶子结点
{
ret = priority_com(pTree->value, pTree->rchild->value);
if (ret < 0)
{
printf("3. invalid express, exit.");
exit(-1);
}
else if (ret == 1)//当前节点的优先级大于右子树, 又子树需要加括号, 防误解
{
printf("%c", '(');
flag_r = 1;
}
}
in_order_traverser(pTree->rchild);
if (flag_r == 1)
{
printf("%c", ')');
flag_r = 0;
}
}
}
//递归后序遍历
void post_order_reserver_tree(tBINARY_TREE *pTree)
{
if (pTree != NULL)
{
post_order_reserver_tree(pTree->lchild);
post_order_reserver_tree(pTree->rchild);
printf("%c", pTree->value);
}
return;
}
void destroy_binary_tree(tBINARY_TREE *pTree)
{
if (pTree != NULL)
{
destroy_binary_tree(pTree->lchild);
destroy_binary_tree(pTree->rchild);
delete pTree; pTree = NULL;
}
return;
}
static bool is_operator(const char c)
{
if (c == '+'
|| c == '-'
|| c == '*'
|| c == '/'
|| c == '('
|| c == ')')
return true;
return false;
}
static int priority_com(int operator1, int operator2)
{
if (operator1 == '*' || operator1 == '/')
{
if (operator2 == '+' || operator2 == '-')
return 1;
}
return 0;
}
int main(void)
{
const char suffix_express[] = "ab+cde+**";
tBINARY_TREE *pTree = suffix_express_create_binary_tree(suffix_express);
printf("old suffix express:%s\n", suffix_express);
printf("new suffix express:");
post_order_reserver_tree(pTree);
printf("\nnew prefix express:");
pre_order_reserver_tree(pTree);
printf("\nnew infix express:");
in_order_traverser(pTree);
printf("\n");
destroy_binary_tree(pTree);
return 0;
}
测试结果:
old suffix express:ab+cde+**
new suffix express:ab+cde+**
new prefix express:*+ab*c+de
new infix express:(a+b)*c*(d+e)