面试题6:重建二叉树
来源:互联网 发布:mac怎么卸载java 编辑:程序博客网 时间:2024/05/16 08:16
struct BinaryTreeNode{ int m_nValue; BinaryTreeNode * m_pLeft; BinaryTreeNode * m_pRight;};
思路:根据前序遍历和中序遍历的规律,前序遍历中第一个元素是根节点,在中序遍历中找到这个元素,在这个元素之前的数字就是这个元素的左结点,后面的是它的右结点。
之后再利用递归,对左结点和右结点分别做同样的操作。
前序遍历:1,2,4,7,3,5,6,8
中序遍历:4,7,2,1,5,3,8,6
(1)根节点是1,在中序遍历中找到1,1之前的4 7 2都是1的左结点,5 3 8 6都是1的右结点,所以1有3个左结点,4个右结点,在前序遍历中1之后的3个数使它左结点,最后4个数是它右结点,所以可以划分为
左结点的前序遍历2 4 7
左结点的中序遍历4 7 2
右结点的前序遍历3 5 6 8
右结点的中序遍历5 3 8 6
(2)对划分之后的序列做同样的步骤,先找出根节点,即前序遍历中的第一个元素2,2就是当前的根节点,中序遍历中2在最后一个位置,所以它没有右结点,右结点数为0不构建右子树,左结点有2个,构建左子树
再划分为 4 7(前序)和4 7(中序)
(3)再划分,4是根节点,中序遍历7在4之后,所以是它右结点,左结点数为0,不构建它的左子树,构建右子树
(4)创建结点,并设置value为7,前序遍历和中序遍历都只剩一个7,所以将当前结点返回,4的右结点7已构建好向上返回,即2的左子树已构建完毕,因为2的右子树为0,所以继续向上返回,即根节点的左子树已构建完毕,之后在对根节点的右子树做同样的步骤即可。
struct BinaryTreeNode{ int m_nValue; BinaryTreeNode * m_pLeft; BinaryTreeNode * m_pRight;}; //(前序遍历起始位置,前序遍历结束位置,中序遍历起始位置,中序遍历结束位置)BinaryTreeNode* ConstructCore(int * startPreorder,int * endPreorder,int * startInorder,int * endInorder){//前序遍历的第一个元素是根节点的值int rootValue=startPreorder[0];BinaryTreeNode * root=new BinaryTreeNode();root->m_nValue=rootValue;root->m_pLeft=root->m_pRight=NULL;//如果前序遍历起始位置等于结束位置,即只要一个元素if(startPreorder==endPreorder){///如果前序遍历中只剩一个元素,那么中序遍历中也只有一个元素,并且它们元素值是相等的if(startInorder==endInorder&&*startInorder==*startPreorder)return root;else//不相等抛出异常throw exception("invalid input");}int * rootInorder=startInorder;//在中序遍历中找到根节点的值while(rootInorder<=endInorder&&*rootInorder!=rootValue)rootInorder++;//如果遍历完毕但没有找到根节点的值,抛出异常if(rootInorder==endInorder && *rootInorder!=rootValue)throw exception("invalid input");int leftLength=rootInorder-startInorder;//根据中序遍历计算当前结点左子树的结点数int * leftPreorderEnd=startPreorder+leftLength;//左子树的结点在前序遍历中的结束位置 //递归构建左右子树if(leftLength>0){//构建左子树root->m_pLeft=ConstructCore(startPreorder+1,leftPreorderEnd,startInorder,rootInorder);}if(leftLength<endPreorder-startPreorder){//构建右子树root->m_pRight=ConstructCore(leftPreorderEnd+1,endPreorder,rootInorder+1,endInorder);}}BinaryTreeNode * Construct(int * preorder,int * inorder,int length){if(preorder==NULL||inorder==NULL||length<=0){return NULL;}return ConstructCore(preorder,preorder+length-1,inorder,inorder+length-1);}
代码步骤:
(1)保存前序遍历中第一个元素的值value
(2)创建节点,并将value赋值给节点,左右子树设为null
(3)判断前序遍历中是否只剩一个元素,如果是再判断和当前中序遍历序列中的第一个元素是否相等,不相等抛出异常,相等返回之前创建的结点,如果不止一个元素继续执行下一步
(4)根据value找出根节点在中序遍历中的位置rootInOrder
(5)判断是否找到,没有找到抛出异常,找到继续下一步
(6)根据根节点在中序遍历的位置,计算出左结点的个数和右结点的个数
(7)根据左右结点的个数计算出要划分的位置
(8)递归构建左右子树
- 面试题6:重建二叉树
- 重建二叉树(面试题 6)
- 面试题6:重建二叉树
- 面试题6- 重建二叉树
- 面试题6 重建二叉树
- 面试题6:重建二叉树
- 面试题6 重建二叉树
- 面试题6:重建二叉树
- 面试题6:重建二叉树
- 面试题6:重建二叉树
- 面试题6:重建二叉树
- 面试题6:重建二叉树
- 面试题6:重建二叉树
- 面试题6: 二叉树的重建
- 面试题6:重建二叉树
- 【面试题6】重建二叉树
- 面试题6:重建二叉树
- 面试题6:重建二叉树
- Sql cursor 基本应用
- universal-image-loader 配置
- HashSet源码分析
- Android连接远程数据库
- 最大报销额_1052_01背包问题
- 面试题6:重建二叉树
- Android Studio 安装教程(Windows)(续)
- R中的含有千分位分隔符数值无法转换
- Pro Vim学习笔记
- Game - HDU 3389 阶梯博弈
- 数据科学家要拥有哪些核心素质?
- python 类属性和实例属性
- HashTable源码分析
- 第一次作业:源代码计算器之目标一