重建二叉树

来源:互联网 发布:淘宝网怎么抢红包 编辑:程序博客网 时间:2024/06/06 03:14

对于一颗二叉树,可以根据先序遍历(后序遍历)和中序遍历重新还原出二叉树。

根据先序遍历和中序遍历还原二叉树的主要思想:

1、先序遍历序列的第一个元素必定是根节点,可以由此获取二叉树的根节点。

2、根据根节点,在中序遍历序列中查找该节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列必定在根节点的左子树中,而根节点右边的序列必定在右子树中。由此可以知道先序遍历中左子树以及右子树的起止位置。

3、分别对左子树和右子树重复上述的过程,直至所有的子树的起止位置相等时,说明已经到达叶子节点,遍历完毕。

代码如下:

[cpp] view plaincopy
  1. #ifndef __FUNCTION_H__  
  2. #define __FUNCTION_H__  
  3. #include <iostream>  
  4.   
  5. using namespace std;  
  6. struct BinaryTreeNode  
  7. {  
  8.     int nodeValue;  
  9.     BinaryTreeNode *pLeft;  
  10.     BinaryTreeNode *pRight;  
  11. };  
  12.   
  13. BinaryTreeNode * BuildRecursivly(int *pPrevOrderStart, int *pPrevOrderEnd, int *pInOrderStart, int *pInOrderEnd)  
  14. {  
  15.     //在先序遍历序列中取出第一个元素即为根节点元素  
  16.     int value = pPrevOrderStart[0];  
  17.     //构造根节点  
  18.     BinaryTreeNode *root = new BinaryTreeNode;  
  19.     root->nodeValue = value;  
  20.     root->pLeft = root->pRight = NULL;  
  21.     //递归结束的情况,即只剩一个叶子节点  
  22.     if(pPrevOrderStart == pPrevOrderEnd)  
  23.     {  
  24.         if(pInOrderStart == pInOrderEnd && *pPrevOrderStart == *pInOrderStart)  
  25.             return root;  
  26.         else  
  27.             throw std::exception();  
  28.     }  
  29.     //在中序遍历序列中找出根节点的位置  
  30.     int *pInOrderCursor = pInOrderStart;  
  31.     while(pInOrderCursor < pInOrderEnd && *pInOrderCursor != value)  
  32.     {  
  33.         pInOrderCursor++;  
  34.     }  
  35.     if(pInOrderCursor == pInOrderEnd && *pInOrderCursor != value)  
  36.     {  
  37.         throw std::exception();  
  38.     }  
  39.     //取得左子树的长度以及在先序遍历中取得左子树的起始位置  
  40.     int leftTreeLen = pInOrderCursor - pInOrderStart;  
  41.     int *pPrevOrderLeftTreeEnd = pPrevOrderStart + leftTreeLen;  
  42.     //如果左子树存在,则递归左子树  
  43.     if(leftTreeLen > 0)  
  44.     {  
  45.         root->pLeft = BuildRecursivly(pPrevOrderStart+1, pPrevOrderLeftTreeEnd,  
  46.                                       pInOrderStart, pInOrderCursor-1);  
  47.     }  
  48.     //如果右子树存在,则递归右子树  
  49.     if((pPrevOrderEnd-pPrevOrderStart) > leftTreeLen)  
  50.     {  
  51.         root->pRight = BuildRecursivly(pPrevOrderLeftTreeEnd+1, pPrevOrderEnd,  
  52.                                        pInOrderCursor+1, pInOrderEnd);  
  53.     }  
  54.   
  55.     return root;  
  56. }  
  57.   
  58. BinaryTreeNode * BulidBinaryTree(int *szPrevOrder, int *szInOrder, int nodeNum)  
  59. {  
  60.     if(szPrevOrder == NULL || szInOrder == NULL)  
  61.         return NULL;  
  62.     return BuildRecursivly(szPrevOrder, szPrevOrder+nodeNum-1,  
  63.                            szInOrder, szInOrder+nodeNum-1);  
  64. }  
  65.   
  66. /*先序遍历*/  
  67. void PrevOrder(BinaryTreeNode *root)  
  68. {  
  69.     if(root == NULL)  
  70.         return;  
  71.     //根  
  72.     cout<<root->nodeValue<<' ';  
  73.     //左子树  
  74.     if(root->pLeft != NULL)  
  75.         PrevOrder(root->pLeft);  
  76.     //右子树  
  77.     if(root->pRight != NULL)  
  78.         PrevOrder(root->pRight);  
  79. }  
  80.   
  81. /*中序遍历*/  
  82. void InOrder(BinaryTreeNode *root)  
  83. {  
  84.     if(root == NULL)  
  85.         return;  
  86.     //左子树  
  87.     if(root->pLeft != NULL)  
  88.         InOrder(root->pLeft);  
  89.     //根  
  90.     cout<<root->nodeValue<<' ';  
  91.     //右子树  
  92.     if(root->pRight != NULL)  
  93.         InOrder(root->pRight);  
  94. }  
  95.   
  96. /*后序遍历*/  
  97. void PostOrder(BinaryTreeNode *root)  
  98. {  
  99.     if(root == NULL)  
  100.         return;  
  101.     //左子树  
  102.     if(root->pLeft != NULL)  
  103.         PostOrder(root->pLeft);  
  104.     //右子树  
  105.     if(root->pRight != NULL)  
  106.         PostOrder(root->pRight);  
  107.     //根  
  108.     cout<<root->nodeValue<<' ';  
  109. }  
  110.   
  111. #endif  


主函数:

[cpp] view plaincopy
  1. #include <iostream>  
  2. #include "function.h"  
  3.   
  4. using namespace std;  
  5.   
  6. /*重建二叉树*/  
  7. int main()  
  8. {  
  9.     int szPrevOrder[] = {1, 2, 4, 7, 3, 5, 6, 8};   //二叉树的先序遍历  
  10.     int szInOrder[] = {4, 7, 2, 1, 5, 3, 8, 6};     //二叉树的中序遍历  
  11.     int nodeNum = sizeof(szPrevOrder)/sizeof(int);  
  12.     BinaryTreeNode *root = BulidBinaryTree(szPrevOrder, szInOrder, nodeNum);  
  13.     cout<<"PrevOrder: ";  
  14.     PrevOrder(root);  
  15.     cout<<endl<<"InOrder:   ";  
  16.     InOrder(root);  
  17.     cout<<endl<<"PostOrder: ";  
  18.     PostOrder(root);  
  19.     cout<<endl;  
  20.   
  21.     return 0;  
  22. }  
0 0