後綴表達式建立二叉樹並遍歷測試

/* 後綴表達式建立二叉樹並遍歷測試
 * 原理:
   掃描後綴表達式,遇到操作數時即建立單二叉樹節點, 左右指針都爲空,放入棧中, 遇到
   操作符時也建立單二叉樹節點, 但是節點的左右指針需要取棧頂元素,即此時依次從棧頂
   出棧的元素分別作爲當前掃描節點的右,左子樹(注意順序), 之後也將該節點進棧, 循環
   該步驟直到後綴表達式結尾, 此時棧頂元素即爲建立好的二叉樹的根節點.

   可以用二叉樹的逆波蘭式與原始表達式對比驗證, 同時可以打印中序遍歷, 得到自然表達式.
   後綴表達式測試用例: "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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章