树的先序、中序、后序

给出树的先序、中序、后序 中两种,求另一种序列


已知 :必须要有中序才能唯一确定树

先序 : A -- B -- D -- H -- E -- C -- F -- G

中序 : H -- D -- B -- E -- A -- F -- C -- G

后序 : H -- D -- E -- B -- F -- G -- C -- A


先序 中序 求后序如下:

先序中第一就是 root

那么根据中序很容易就知道如下:

左子树 :  H -- D -- B -- E

右子树 : F -- C -- G

然后有根据 先序中 : B -- D -- H -- E  得到 B 是 这个子树的 root

左子树 : H -- D

右子树 : E

这么推下去就得到了树的结构了。

### 构造二叉的核心原理 构造二叉可以通过遍历遍历来完成,也可以通过后序遍历遍历来完成。核心思想在于利用不同遍历方式的特点找到根节点的位置,并以此划分左子右子。 #### 方法一:基于遍历遍历构建二叉遍历中,第一个元素总是当前子的根节点。而在中遍历中,根节点左侧的部分表示左子,右侧部分表示右子。因此可以递归地分割中列并重建左右子。 以下是具体实现方法: ```java class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class Solution { public TreeNode buildTree(int[] preorder, int[] inorder) { return helper(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); } private TreeNode helper(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) { if (preStart > preEnd || inStart > inEnd) { return null; } // 找到根节点 int rootVal = preorder[preStart]; TreeNode root = new TreeNode(rootVal); // 查找根节点在中遍历中的位置 int index = findIndex(inorder, inStart, inEnd, rootVal); // 计算左子长度 int leftSize = index - inStart; // 递归构建左子右子 root.left = helper(preorder, preStart + 1, preStart + leftSize, inorder, inStart, index - 1); root.right = helper(preorder, preStart + leftSize + 1, preEnd, inorder, index + 1, inEnd); return root; } private int findIndex(int[] array, int start, int end, int value) { for (int i = start; i <= end; i++) { if (array[i] == value) { return i; } } return -1; // 如果未找到则抛异常或处理错误情况 } } ``` 上述代码实现了通过遍历遍历构建二叉的功能[^3]。 --- #### 方法二:基于后序遍历遍历构建二叉后序遍历中,最后一个元素始终是当前子的根节点。同样,在中遍历中,根节点左侧为左子,右侧为右子。这种方法也采用递归来解决问题。 以下是具体的实现方法: ```java public class SolutionPostInOrder { public TreeNode buildTree(int[] postorder, int[] inorder) { return helper(postorder, 0, postorder.length - 1, inorder, 0, inorder.length - 1); } private TreeNode helper(int[] postorder, int postStart, int postEnd, int[] inorder, int inStart, int inEnd) { if (postStart > postEnd || inStart > inEnd) { return null; } // 后序遍历的最后一个是根节点 int rootVal = postorder[postEnd]; TreeNode root = new TreeNode(rootVal); // 寻找根节点在中遍历中的索引 int index = findIndex(inorder, inStart, inEnd, rootVal); // 左子大小 int leftSize = index - inStart; // 递归构建右子左子(注意后序遍历的方向) root.right = helper(postorder, postEnd - 1 - leftSize + 1, postEnd - 1, inorder, index + 1, inEnd); root.left = helper(postorder, postStart, postEnd - 1 - leftSize, inorder, inStart, index - 1); return root; } private int findIndex(int[] array, int start, int end, int value) { for (int i = start; i <= end; i++) { if (array[i] == value) { return i; } } return -1; } } ``` 此代码展示了如何通过后序遍历遍历构建二叉[^2]。 --- ### 思路总结 无论是通过加中还是后序加中的方式,都需要明确以下几点: - **根节点定位**:的第一个元素或者后序的最后一个元素作为根节点。 - **分治法应用**:根据根节点将中划分为两部分,分别对应左子右子。 - **递归调用**:不断缩小范围直到无法继续分解为止。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值