编程之美---重建二叉树
学过数据结构和算法的人都能很快的写出二叉树的三种遍历次序。
那么如果已经知道了遍历的结果,能不能把一颗二叉树重新构造出来呢?
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 }