题目:根据二叉树的前序和中序遍历结果,还原这颗二叉树。
例如,一颗的二叉树如下所示,
=======二叉树=======
1
2 3
4 5 6 7
8
=======二叉树=======
根据二叉树的遍历策略:
前序遍历策略:1)访问根节点;2)访问左子树;3)访问右子树。
中序遍历策略:1)访问左子树;2)访问根节点;3)访问右子树。
得到前序和中序遍历的结果如下,
前序遍历为:12485367,
中序遍历为:84251637。
现在,已知,二叉树的前序遍历结果、中序遍历的结果,求原二叉树。
分析:
1. 数据结构
需要定义Node节点,Node节点包含值/键 key,和指向左右子树的引用left、right。前序中序的遍历结果,存储在数组中。
2. 策略
选择递归策略解题,能用递归解题的原因在于,原问题,经过一趟的处理/划分后,能变成一个规模更小的子问题。每一趟处理,得到一个节点Node,通过把子问题处理结果subNode返回给父问题得到的Node的left、right,把父子问题的Node关联起来,最终得到连通的原二叉树。
3. 编程语言
各种编程语言都可以,我用的是Java。
/** * @author tanliwei * @email tanliweii@qq.com * @time 2016-4-28下午10:15:32 */ public class RestoreBinaryTreeByTwoTraverseOder { // // ===binary tree=== // 1 // // 2 3 // // 4 5 6 7 // // 8 // ===binary tree=== // // preorder traversal: 12485367; inorder traversal : 84251637; // // input : Preoder & inoder traversal results of a binary tree(e.g. above) // output : The orginal binary tree // public Node restore(int[] preorder, int[] inorder) { if (preorder.length == 0 || inorder.length == 0) { return null; } Node root = new Node(preorder[0]); int rootIndexInInorder = findIndexByValue(preorder[0], inorder); int lengthOfSubPreorder1 = rootIndexInInorder; int[] subPreorder1 = {}; if (lengthOfSubPreorder1 > 0) { // generate subPreorder1 2485 subPreorder1 = new int[lengthOfSubPreorder1]; System .arraycopy(preorder, 1, subPreorder1, 0, lengthOfSubPreorder1); } // remain subPreorder int lengthOfSubPreorder2 = preorder.length - lengthOfSubPreorder1 - 1; int[] subPreorder2 = {}; if (lengthOfSubPreorder2 > 0) { // generate subPreorder2 367 subPreorder2 = new int[lengthOfSubPreorder2]; System.arraycopy(preorder, preorder.length - lengthOfSubPreorder2, subPreorder2, 0, lengthOfSubPreorder2); } int lengthOfSubinorder1 = rootIndexInInorder; int[] subinorder1 = {}; if (lengthOfSubinorder1 > 0) { subinorder1 = new int[lengthOfSubinorder1]; // generate subPreorder1 8425 System.arraycopy(inorder, 0, subinorder1, 0, lengthOfSubinorder1); } // remain subInorder int lengthOfSubInorder2 = preorder.length - lengthOfSubinorder1 - 1; int[] subinorder2 = {}; if (lengthOfSubInorder2 > 0) { subinorder2 = new int[lengthOfSubInorder2]; // generate subPreorder2 637 System.arraycopy(inorder, inorder.length - lengthOfSubInorder2, subinorder2, 0, lengthOfSubPreorder2); } root.setLeft(restore(subPreorder1,subinorder1)); root.setRight(restore(subPreorder2,subinorder2)); return root; } /** * find the index of the same value of compareValue in array a * * @param compareValue * @param a * @return */ public int findIndexByValue(int compareValue, int[] a) { if (null == a || a.length == 0) { return -1; } for (int i = 0; i < a.length; i++) { if (a[i] == compareValue) { return i; } } return -1; } public static void main(String[] args) { //12485367; inorder traversal : 84251637; int[] preorder = {1,2,4,8,5,3,6,7}; int[] inorder = {8,4,2,5,1,6,3,7}; RestoreBinaryTreeByTwoTraverseOder runner = new RestoreBinaryTreeByTwoTraverseOder(); Node head = new Node(-1);// head = runner.restore(preorder, inorder); if(null == head){ return ; } runner.preorderTraverse(head); System.out.println(); runner.inorderTraverse(head); } /** * Traverse in preorder * @param root */ public void preorderTraverse(Node root){ if(null == root) return; System.out.print(root.getKey()); preorderTraverse(root.getLeft()); preorderTraverse(root.getRight()); } /** * Traverse in inorder * @param root */ public void inorderTraverse(Node root){ if(null == root) return; inorderTraverse(root.getLeft()); System.out.print(root.getKey()); inorderTraverse(root.getRight()); } } class Node { public Node() { }; public Node(int key) { this.key = key; } private int key; private Node left; private Node right; public Node getLeft() { return left; } public void setLeft(Node left) { this.left = left; } public Node getRight() { return right; } public void setRight(Node right) { this.right = right; } public int getKey() { return key; } public void setKey(int key) { this.key = key; } }
代码如上,运行测试可行,尚未进行更多的验证。如有遗漏,欢迎指正。
该问题可以继续拓展为,已知中序、后序遍历结果,还原原二叉树,等等。
相关推荐
数据结构算法及应用 上机作业 谦虚中序遍历顺序&中序后续遍历顺序,还原二叉树并输出
二叉树的遍历,全部用递归实现,很有规律! 二叉树的遍历,全部用递归实现,很有规律
本文实例讲述了Python利用前序和中序遍历结果重建二叉树的方法。分享给大家供大家参考,具体如下: 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含...
4. **已知二叉树前序和中序序列还原二叉树** 前序遍历的第一个元素是根节点,中序遍历将根节点左侧的元素放在左侧子树,右侧的元素放在右侧子树。因此,可以先找到前序遍历中根节点的位置,然后分别构建左侧和右侧...
题目:从先序和中序遍历结果恢复二叉树。 分析:输入先序序列和中序序列,从而得到一个完整的二叉树。 步骤:1.找到root,前序遍历的第一节点G就是root。 2.继续观察前序遍历GDAFEMHZ,除了知道G是root,剩下的节点...
本篇文章将详细介绍如何根据二叉树的后序遍历和中序遍历序列来还原二叉树。 #### 1. 二叉树的基础概念 二叉树是由节点组成的一种数据结构,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。在二叉树中...
前序和中序 构造二叉树的java代码, 其中main方法用前序遍历 验证了一下还原的代码
通过先序遍历和中序遍历后的序列还原二叉树 二叉树遍历序列还原是计算机科学中的一种重要问题,它广泛应用于数据结构、算法设计和软件开发等领域。 Given a pair of sequences generated by preorder and inorder ...
本篇文章介绍了一个通过给定的二叉树的前序遍历序列和中序遍历序列来还原二叉树的过程。这个过程不仅能够加深对二叉树的理解,还能够提高解决实际问题的能力。 #### 二、二叉树的基本概念 二叉树是由一个或多个节点...
二叉树的遍历是理解其结构和性质的关键,通常包括前序遍历、中序遍历和后序遍历三种方式。前序遍历顺序是根节点、左子树、右子树(NLR),中序遍历顺序是左子树、根节点、右子树(LNR),后序遍历顺序是左子树、右子...
该问题中,会给出二叉树的前序与中序的遍历序列(没有重复元素)preorder和inorder,还原二叉树。 递归版(哈希表): 前序序列第一个值一定是根节点的值; 根据得到的根节点,在中序序列中可以得到二叉树根的索引 ...
无论是递归还是非递归方式,每种遍历都有其特定的应用场景和优势,例如前序遍历常用于复制二叉树,中序遍历在二叉搜索树中用于排序,而后序遍历则常用于计算表达式树等。通过不断实践和练习,我们可以更好地运用这些...
通过前序遍历序列和中序遍历序列可以还原出原始的二叉树结构。在文件中,给定的前序遍历序列为ABDFECGH,中序遍历序列为DFBEAGHC,根据这两个序列,可以递归地构建出相应的二叉树结构。 7. 算法的参数设置和函数...
二叉树的遍历有三种基本方法:前序遍历、中序遍历和后序遍历,它们分别按照不同的顺序访问树中的每一个节点。 1. 前序遍历(根-左-右): - 访问根节点。 - 遍历左子树。 - 遍历右子树。 2. 中序遍历(左-根-右...
例如,将中序遍历序列给A,然后构造一个与加密二叉树前序遍历相同的虚拟二叉树,并将其前序遍历和后序遍历分别给B和C,这样就分散了密钥。若需分发给更多人,可以继续用后序遍历构造新的虚拟二叉树并分配其前序和...
3. 利用线索的递归中序遍历和后序遍历:类似地,根据左线索或右线索调整遍历顺序。 两种线索化方法: 1. 静态线索化:在构建二叉树时就进行线索化,适用于树结构稳定且不常变化的情况。 2. 动态线索化:在遍历过程...
- 根据前序和中序遍历结果还原二叉树 - 根据后序和中序遍历结果还原二叉树 3. 树的修改和查询: - 查找树中的最大值和最小值节点 - 查找节点的父节点 - 在二叉搜索树中查找节点 - 在二叉搜索树中插入和删除...
106题是LeetCode上的一道经典二叉树问题,要求根据给定的中序遍历(inorder)和后序遍历(postorder)序列来构造二叉树。二叉树的遍历有三种基本方式:前序遍历(root -> left -> right),中序遍历(left -> root -...
例如题目中的选择题第五题,给出的前序遍历序列和中序遍历序列分别为“stuwv”和“uwtvs”,我们可以通过这两个序列推断出后序遍历序列为“wutsv”。 ##### 4. 哈夫曼树 - **定义**:一种带权路径长度最短的二叉树...