已知二叉树的中序和前序序列(或后序)求解树

来源:互联网 发布:nodejs 遍历json数组 编辑:程序博客网 时间:2024/05/20 04:51

http://www.cnblogs.com/bmrs/archive/2010/08/19/SloveTree.html

这种题一般有二种形式,共同点是都已知中序序列。如果没有中序序列,是无法唯一确定一棵树的。

一、已知二叉树的前序序列和中序序列,求解树。

1、确定树的根节点。树根是当前树中所有元素在前序遍历中最先出现的元素。

2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点左边和右边都为空,则根节点已经为叶子节点。

3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复123步,直到所有的节点完成定位。

二、已知二叉树的后序序列和中序序列,求解树。

1、确定树的根。树根是当前树中所有元素在后序遍历中最后出现的元素。

2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点左边和右边都为空,则根节点已经为叶子节点。

3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复123步,直到所有的节点完成定位。

举例说明:根据已知求解二叉树

中序序列 HLDBEKAFCG
后序序列 LHDKEBFGCA

1、在后序序列LHDKEBFGCA中最后出现的元素为AHLDBEK|A|FCG
2
、在后序序列LHDKEB中最后出现的元素为BHLD|B|EK|A|FCG
3
、在后序序列LHD中最后出现的元素为DHL|D|B|EK|A|FCG
4、在后序序列LH中最后出现的元素为HH|L|D|B|EK|A|FCG
5、在后序序列KE中最后出现的元素为EH|L|D|B|E|K|A|FCG
5、在后序序列FGC中最后出现的元素为CH|L|D|B|E|K|A|F|C|G
6
、所有元素都已经定位,二叉树求解完成。

 

 #include <iostream> #include <cstring> using namespace std;  char pre[50] = "ABDHLEKCFG";        //前序序列 char mid[50] = "HLDBEKAFCG";        //中序序列 char post[50] = "LHDKEBFGCA";        //后序序列  typedef struct _Node {     char v;     struct _Node *left;     struct _Node *right; _Node():left(NULL),right(NULL){}  //每次初始化左右子树指针 }Node, *PNode;  void PostTravelTree(PNode pn);        //树的后序递归遍历 void PreTravelTree(PNode pn);         //树的前序递归遍历 void PreMidCreateTree(PNode &pn, int i, int j, int len);        //利用前序中序序列创建树 void PostMidCreateTree(PNode &pn, int i, int j, int len);       //利用后序中序序列创建树 int Position(char c);                 //确定c在中序序列mid中的下标,假设树的各个节点的值各不相同   int main()  {      PNode root1 = NULL, root2= NULL;     PreMidCreateTree(root1, 0, 0, strlen(mid));     PostTravelTree(root1); cout<<endl;         PostMidCreateTree(root2, strlen(post)-1, 0, strlen(mid));     PreTravelTree(root2); cout<<endl;     system("pause");     return 0; }   int Position(char c) {     return strchr(mid,c)-mid; }   /*  利用前序中序序列创建树,参考了http://hi.baidu.com/sulipol/blog/item/f01a20011dcce31a738b6524.html  *的实现,代码十分简洁,竟然只有短短的"令人发指"的8行,递归实在太彪悍了!!!!!!!!!!!!!!!!!!!!!  *        i: 子树的前序序列字符串的首字符在pre[]中的下标  *        j: 子树的中序序列字符串的首字符在mid[]中的下标  *      len: 子树的字符串序列的长度  */ void PreMidCreateTree(PNode &pn, int i, int j, int len) {     if(len <= 0)         return;          pn = new Node;     pn->v = pre[i];     int m = Position(pre[i]);     PreMidCreateTree(pn->left, i+1, j, m-j);            //m-j为左子树字符串长度     PreMidCreateTree(pn->right, i+(m-j)+1, m+1, len-1-(m-j));    //len-1-(m-j)为右子树字符串长度 }   /*  利用后序中序序列创建树  *        i: 子树的后序序列字符串的尾字符在post[]中的下标  *        j: 子树的中序序列字符串的首字符在mid[]中的下标  *      len: 子树的字符串序列的长度  */ void PostMidCreateTree(PNode &pn, int i, int j, int len) {     if(len <= 0)         return;      pn = new Node;     pn->v = post[i];     int m = Position(post[i]);     PostMidCreateTree(pn->left, i-1-(len-1-(m-j)), j, m-j);//注意参数:m-j左子树的长度,len-1-(m-j)右子树的长度     PostMidCreateTree(pn->right, i-1, m+1, len-1-(m-j)); }   void PostTravelTree(PNode pn)        //后序递归遍历 {     if(pn)     {         PostTravelTree(pn->left);             PostTravelTree(pn->right);         cout<<pn->v<<" ";     } }   void PreTravelTree(PNode pn)        //前序递归遍历 {     if(pn)     {         cout<<pn->v<<" ";         PreTravelTree(pn->left);             PreTravelTree(pn->right);     } }


原创粉丝点击