已知前序中序,重建二叉树,输出后序

    具体算法就是用前序的第一个字母(根节点)去中序查找该字母,把中序分成前后2节,前一节是左子树,长度len_l,后一节是右子树,长度len_r。且前序字符串的长度也可以根据前序分析得到的长度len_l和len_r分成这样的2节。接着递归构建。

如:
//前序序列 "ABDHLEKCFG";
//中序序列 "HLDBEKAFCG";
1. 用A去中序序列查找,将其分为HLDBEK和FCG,左子树的长度为6,右子树长度为3。
2. 把前序序列从A之后根据上句的左右子树的长度分为BDHLEK和CFG,
3. 递归构建,R(HLDBEK,BDHLEK) 和 R(FCG,CFG)。

#include <string>
#include <iostream>
#include <assert.h>
using namespace std;
struct node
{
    char c;
    node *lchild, *rchild;
};
class tree
{
private:
    string preorder, inorder;
    node *root;
public:
    tree()
    {
        root = NULL;
        cout<<"input two string:\n";
        while (cin>>preorder>>inorder)//ABDHLEKCFG HLDBEKAFCG
        {
            RebuildTree(preorder, inorder, root);
            postorder(root);
            cout<<"\ninput two string:\n";
        }
    }
    ~tree(){}
    void RebuildTree(string prestr, string instr, node* &ptemp)//指针的引用
    {
        assert(prestr.length() == instr.length());
        if (prestr.length() == 0)
        {
            return;
        }
        ptemp = new node;
        char c;
        c = ptemp->c = prestr[0];
        ptemp->lchild = NULL;
        ptemp->rchild = NULL;
        int pos = instr.find(c);
        int left = pos;
        int right = instr.length() - pos -1;
        if (left > 0)
        {
            RebuildTree(prestr.substr(1, left), instr.substr(0, left), ptemp->lchild);
        }
        if (right > 0)
        {
            RebuildTree(prestr.substr(left+1, right), instr.substr(left+1, right), ptemp->rchild);
        }
    }
    void postorder(node *p)
    {
        if (p != NULL)
        {
            postorder(p->lchild);
            postorder(p->rchild);
            cout<<p->c;
        }
    }
};
void main()
{
    tree t;
    system("pause");
}

  

posted on 2015-04-12 19:25  大宴天下  阅读(270)  评论(0编辑  收藏  举报