`
samuschen
  • 浏览: 405656 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

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

 
阅读更多

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

(解释部分来自http://www.slyar.com/blog/ )

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

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

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

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

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

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

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

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

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

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

中序序列 HLDBEKAFCG
后序序列 LHDKEBFGCA

1、在后序序列LHDKEBFGCA中最后出现的元素为A,HLDBEK|A |FCG
2、在后序序列LHDKEB中最后出现的元素为B,HLD|B |EK|A |FCG
3、在后序序列LHD中最后出现的元素为D,HL|D |B|EK|A|FCG
4、在后序序列LH中最后出现的元素为H,H |L|D|B|EK|A|FCG
5、在后序序列KE中最后出现的元素为E,H |L|D|B|E |K|A|FCG

5、在后序序列FGC中最后出现的元素为C,H |L|D|B|E|K|A|F|C |G
6、所有元素都已经定位,二叉树求解完成。

                 
A
              /     \
             B       C
            / \     /  \
           D  E     F   G
          /    \
         H      K                    
          \                         
           L                     
代码如下:
  1  /*
  2      功能: 1.利用树的前序和中序序列创建树
  3            2.利用树的后序和中序序列创建树
  4  */
  5  #include  < iostream >
  6  #include  < cstring >
  7  using   namespace  std;
  8  
  9  char  pre[ 50 =   " ABDHLEKCFG " ;         // 前序序列
 10  char  mid[ 50 =   " HLDBEKAFCG " ;         // 中序序列
 11  char  post[ 50 =   " LHDKEBFGCA " ;         // 后序序列
 12  
 13  typedef  struct  _Node
 14  {
 15       char  v;
 16       struct  _Node  * left;
 17       struct  _Node  * right;
 18  }Node,  * PNode;
 19  
 20  void  PostTravelTree(PNode pn);         // 树的后序递归遍历
 21  void  PreTravelTree(PNode pn);         // 树的前序递归遍历
 22  void  PreMidCreateTree(PNode  & pn,  int  i,  int  j,  int  len);         // 利用前序中序序列创建树
 23  void  PostMidCreateTree(PNode  & pn,  int  i,  int  j,  int  len);         // 利用后序中序序列创建树
 24  int  Position( char  c);                 // 确定c在中序序列mid中的下标,假设树的各个节点的值各不相同
 25  
 26  
 27  int  main() 
 28  
 29      PNode root1  =  NULL, root2 =  NULL;
 30  
 31      PreMidCreateTree(root1,  0 0 , strlen(mid));
 34      PostTravelTree(root1); cout << endl;    
 36      PostMidCreateTree(root2, strlen(post) - 1 0 , strlen(mid));
 37      PreTravelTree(root2); cout << endl;    
 38  
 39       return   0 ;
 40  }
 41  
 42  
 43  int  Position( char  c)
 44  {
 45       return  strchr(mid,c) - mid;
 46  }
 47  
 48  
 49  /*   利用前序中序序列创建树,参考了http://hi.baidu.com/sulipol/blog/item/f01a20011dcce31a738b6524.html
 50   *的实现,代码十分简洁,竟然只有短短的"令人发指"的8行,递归实在太彪悍了!!!!!!!!!!!!!!!!!!!!!
 51   *        i: 子树的前序序列字符串的首字符在pre[]中的下标
 52   *        j: 子树的中序序列字符串的首字符在mid[]中的下标
 53   *      len: 子树的字符串序列的长度
 54    */
 55  void  PreMidCreateTree(PNode  & pn,  int  i,  int  j,  int  len)
 56  {
 57       if (len  <=   0 )
 58           return ;
 59      
 60      pn  =   new  Node;
 61      pn -> =  pre[i];
 62       int  m  =  Position(pre[i]);
 63      PreMidCreateTree(pn -> left, i + 1 , j, m - j);             // m-j为左子树字符串长度
 64      PreMidCreateTree(pn -> right, i + (m - j) + 1 , m + 1 , len - 1 - (m - j));     // len-1-(m-j)为右子树字符串长度
 65  }
 66  
 67  
 68  /*   利用后序中序序列创建树
 69   *        i: 子树的后序序列字符串的尾字符在post[]中的下标
 70   *        j: 子树的中序序列字符串的首字符在mid[]中的下标
 71   *      len: 子树的字符串序列的长度
 72    */
 73  void  PostMidCreateTree(PNode  & pn,  int  i,  int  j,  int  len)
 74  {
 75       if (len  <=   0 )
 76           return ;
 77  
 78      pn  =   new  Node;
 79      pn -> =  post[i];
 80       int  m  =  Position(post[i]);
 81      PostMidCreateTree(pn -> left, i - 1 - (len - 1 - (m - j)), j, m - j); // 注意参数:m-j左子树的长度,len-1-(m-j)右子树的长度
 82      PostMidCreateTree(pn -> right, i - 1 , m + 1 , len - 1 - (m - j));
 83  }
 84  
 85  
 86  void  PostTravelTree(PNode pn)         // 后序递归遍历
 87  {
 88       if (pn)
 89      {
 90          PostTravelTree(pn -> left);    
 91          PostTravelTree(pn -> right);
 92          cout << pn -> v << "   " ;
 93      }
 94  }
 95  
 96  
 97  void  PreTravelTree(PNode pn)         // 前序递归遍历
 98  {
 99       if (pn)
100      {
101          cout << pn -> v << "   " ;
102          PreTravelTree(pn -> left);    
103          PreTravelTree(pn -> right);
104      }
105  }
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics