编程之美---重建二叉树

学过数据结构和算法的人都能很快的写出二叉树的三种遍历次序。
     那么如果已经知道了遍历的结果,能不能把一颗二叉树重新构造出来呢?

 1 //定义树的长度
 2 #define TREELEN 6
 3 #include<iostream>
 4 using namespace std;
 5 
 6 struct Node
 7 {
 8     struct Node* pLeft;
 9     struct Node* pRight;
10     char value;
11 };
12 
13 void Rebuild(char *pPreOrder,//前序遍历结果
14              char *pInorder,//中序遍历结果
15              int nTreeLen,//树的长度
16              Node **pRoot)//根节点
17 {
18     //检查边界条件
19     if(pPreOrder==NULL ||pInorder==NULL)
20     {
21         return ;
22     }
23     //获得前序遍历的第一个结点
24     Node *pt=new Node ;
25     pt->value=*pPreOrder;
26     pt->pLeft=NULL;
27     pt->pRight=NULL;
28     //如果根节点为空,将该节点设置为根节点,首次会调用
29     if(*pRoot==NULL)
30     {
31         *pRoot=pt;
32     }
33     //如果深度为1,那么已经是叶节点了
34     if(nTreeLen==1)
35     {
36         return;
37     }
38     //在中序遍历中寻找左子树
39     char *pOrgInOrder=pInorder;
40     char *pLeftEnd=pInorder;
41     int ntemp=0;
42     //找到左子树的结尾
43     while(*pPreOrder!=*pLeftEnd)
44     {
45         if(pPreOrder==NULL||pLeftEnd==NULL)
46         {
47             return;
48         }
49         ntemp++;
50         if(ntemp>nTreeLen)
51         {
52             return;
53         }
54         pLeftEnd++;
55     }
56     //确定左子树的长度
57     int nLeftLen=0;
58     nLeftLen=(int)(pLeftEnd-pOrgInOrder);
59     //确定右子树的长度
60     int nRightLen=0;
61     nRightLen=nTreeLen-nLeftLen-1;
62     
63     //重建左子树
64     if(nLeftLen>0)
65     {
66         Rebuild(pPreOrder+1,pInorder,nLeftLen,&((*pRoot)->pLeft));
67     }
68     //重建右子树
69     if(nRightLen>0)
70     {
71         Rebuild(pPreOrder+nLeftLen+1,pInorder+nLeftLen+1,nRightLen,&((*pRoot)->pRight));
72     }
73 }
74 
75 int main()
76 {
77     char PreOrder[]={'a','b','d','c','e','f'};
78     char InOrder[]={'d','b','a','e','c','f'};
79     Node *root=NULL;
80     Rebuild(PreOrder,InOrder,TREELEN,&root);
81 }
View Code

 

posted @ 2014-12-23 22:45  智者无惧  阅读(134)  评论(0编辑  收藏  举报