已知前序中序,重建二叉树,输出后序
具体算法就是用前序的第一个字母(根节点)去中序查找该字母,把中序分成前后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"); }