简单中序算术表达式直接建立二叉树测试

来源:互联网 发布:死神来了5 知乎 编辑:程序博客网 时间:2024/05/22 07:34
/* 简单中序算术表达式转为二叉树, 至于转成了二叉树, 前中后遍历就随意了   1. 将表达式转为后缀表达式, 然后转为二叉树, 或者用2步骤.   2. 理论上来讲, 一个中缀表达式是不能够转换出一个唯一的二叉树的,      但是中缀算术表达式因为有运算符的优先级关系, 建立二叉树时, 需要所有的操作数      都在叶子节点上, 所有的操作符都在父(根)节点上, 这个特征可以生成一个唯一的二叉树   3. 原理: 每次找到最后计算的运算符, 然后去递归处理, 因为'*'和'/'的运算符优先级高于      '+', '-', 这样我们找运算符是应该优先选择'+','-',然后再考虑'*', '/'.      至于括号, 去掉对括号内的内容作同样的递归分析即可, 中序遍历的时候注意将括号恢复. */#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct _tBINARY_TREE_{    int value;    _tBINARY_TREE_ *lchild;    _tBINARY_TREE_ *rchild;}tBINARY_TREE;static int find_split(const char *express, int start, int end){    int tag = -1;    if (express[start] == '(' && express[end] == ')')    {        ++start;        --end;    }    int is_in_braket = 0;    int more_grade = 0;    for (int i = start; i <= end; i++)    {        if (express[i] == '(')            ++is_in_braket;        else if (express[i] == ')')            --is_in_braket;        if ((express[i] == '+' || express[i] == '-')            && is_in_braket == 0)        {            more_grade = 1;            tag = i; //无break, 找最后一个符合条件的运算符, 取顶级的+和-        }        else if ((express[i] == '*' || express[i] == '/')                 && more_grade == 0                 && is_in_braket == 0)        {            tag = i; //无break, 找最后一个符合条件的运算符        }    }    return tag;}static tBINARY_TREE *do_create_binary_tree(const char *express, int start, int end){    tBINARY_TREE *pTree = NULL;    if (start == end)    {        pTree = new tBINARY_TREE;        pTree->value = express[start];        pTree->lchild = NULL;        pTree->rchild = NULL;    }    else    {   //递归调用, 各自创建左右的表达式的对应二叉树        int tag = find_split(express, start, end);        if (tag < 0)        {            printf("1.invalid express, exit.\n");            exit(-1);        }        else        {            pTree = new tBINARY_TREE;            pTree->value = express[tag];        }        if (express[start] == '(' && express[end] == ')')        {            ++start;            --end;        }        pTree->lchild = do_create_binary_tree(express, start, tag-1);        pTree->rchild = do_create_binary_tree(express, tag+1, end);    }    return pTree;}static tBINARY_TREE *create_binary_tree(const char *infix_express){    return do_create_binary_tree(infix_express, 0, strlen(infix_express)-1);}static int priority_com(int operator1, int operator2){    if (operator1 == '*' || operator1 == '/')    {        if (operator2 == '+' || operator2 == '-')            return 1;    }    return 0;}//递归中序遍历二叉树, 需要注意将括号恢复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;        }    } }//递归先序遍历二叉树static void pre_order_traverser(tBINARY_TREE *pTree){    if (pTree != NULL)    {        printf("%c", pTree->value);        pre_order_traverser(pTree->lchild);        pre_order_traverser(pTree->rchild);    } }//递归后序遍历二叉树static void post_order_traverser(tBINARY_TREE *pTree){    if (pTree != NULL)    {        post_order_traverser(pTree->lchild);        post_order_traverser(pTree->rchild);        printf("%c", pTree->value);    } } static void destroy_binary_tree(tBINARY_TREE *pTree) {    if (pTree != NULL)    {        destroy_binary_tree(pTree->lchild);        destroy_binary_tree(pTree->rchild);        delete pTree; pTree = NULL;    } }int main(void){    const char express[] = "a+b*c+((d*e)+f)*g";    //const char express[] = "a*(b-c)";    //const char express[] = "((a+b)*c+d)*e*f+(g-h)*m";    tBINARY_TREE *pTree = create_binary_tree(express);    if (pTree != NULL)    {        printf("prefix order:\n");        pre_order_traverser(pTree);        printf("\n\ninfix order:\n");        in_order_traverser(pTree);        printf("\n\npostfix order:\n");        post_order_traverser(pTree);        printf("\n");        destroy_binary_tree(pTree);    }    return 0;}


0 0
原创粉丝点击