二叉树,根据先序、中序序列,求后续遍历结果
C++版本
输入:
第一行为二叉树先序遍历结果。
第二行为二叉树中序遍历结果。
输出:
二叉树后续遍历结果
样例输入:
426315
623415
样例输出:
632514
完整代码:
#include<bits/stdc++.h>
using namespace std;
char pre[100];
char hou[100];
//定义结构体
typedef struct node{
char data;
struct node *lc,*rc;
} *BTree;
//根据先序、中序建树
BTree build(int l1, int r1, int l2, int r2){
BTree T = new node;
T->data = pre[l1];
T->lc=NULL;
T->rc=NULL;
int pos = l2;
while(hou[pos]!=pre[l1]){
pos++;
}
int cnum = pos-l2;
if(pos>l2){
T->lc = build(l1+1, l1+cnum, l2, pos-1);
}
if(pos<r2){
T->rc = build(l1+cnum+1, r1, pos+1, r2);
}
return T;
}
//后续输出遍历结果
void Hou(BTree T){
if(T!=NULL){
Hou(T->lc);
Hou(T->rc);
cout<<T->data;
}
}
//主函数
int main(){
cin>>pre;
cin>>hou;
BTree T = build(0, strlen(pre)-1, 0, strlen(hou)-1);
Hou(T);
}
java版本
题目描述:输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回后序遍历结果。
说明:假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
节点:
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
代码:
package com.hui.array;
import java.util.HashMap;
import java.util.Map;
/*
修改版本
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回后序遍历结果。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
*/
public class Main {
public static void main(String[] args) {
// 先序遍历数组
int[] preorder = new int[]{4,2,6,3,1,5};
// 中间序遍历数组
int[] inorder = new int[]{6,2,3,4,1,5};
Solution res = new Solution();
// 建立二叉树
TreeNode treeNode = res.buildTree(preorder, inorder);
// 后序输出
res.printHou(treeNode);
}
}
class Solution {
// 用来存中序遍历每个数字的下标
private Map<Integer, Integer> mapIndex;
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || preorder.length == 0) {
return null;
}
mapIndex = new HashMap<>();
int n = preorder.length;
// 构造哈希映射,快速定位到中序数组根节点的下标
for (int i = 0; i < n; i++) {
mapIndex.put(inorder[i], i);
}
return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
}
public TreeNode myBuildTree(int[] preorder, int[] inorder, int preLeftIndex, int preRightIndex, int inLeftIndex, int inrRightIndex) {
// 递归终止条件
if(preLeftIndex > preRightIndex) return null;
// 先序数组的第一个元素就是根元素,找到先序根元素下标
int preRootIndex = preLeftIndex;
// 找到中序根元素下标
int inRootIndex = mapIndex.get(preorder[preRootIndex]);
// 计算左子树大小
int leftSize = inRootIndex - inLeftIndex;
// 新建根节点
TreeNode root = new TreeNode(preorder[preRootIndex]);
// 完善左子树
// 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
root.left = myBuildTree(preorder, inorder, preLeftIndex + 1, preLeftIndex + leftSize, inLeftIndex, inRootIndex - 1);
// 完善右子树
// 先序遍历中「从 左边界+左子树节点数目+1 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
root.right = myBuildTree(preorder, inorder, preLeftIndex + leftSize + 1, preRightIndex, inRootIndex + 1, inrRightIndex);
return root;
}
// 后序输出
public void printHou(TreeNode root) {
if (root == null) return;
printHou(root.left);
printHou(root.right);
System.out.print(" " + root.val + " ");
}
}