問題の説明
事前順序走査用の配列と順序内走査用の配列がそれぞれ与えられ、バイナリ ツリーを構築する必要があります。入力の事前順序トラバーサルと順序トラバーサルの結果のどちらにも重複する数値が含まれていないと仮定します。たとえば、事前順序走査シーケンス {1,2,4,7,3,5,6,8} と順序走査シーケンス {4,7,2,1,5,3,8,6} を入力して、リビルドします。バイナリツリーを返します。
問題分析
バイナリ ツリーの走査順序:
プレオーダー: ルートの左と右、
中間のオーダー: 左のルート、右の
ポストオーダー: 左と右のルート
対応するルート ノードは、事前順序トラバーサル シーケンスから知ることができ、順序トラバーサル シーケンス内のルート ノードの位置によって、左側のサブツリーと右側のサブツリーが分離されます。
次に、左のサブツリーと右のサブツリーに順番にバイナリ ツリーを再帰的に構築します。
コード
/**
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
*
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
package treeAlgorithm;
import java.util.Arrays;
public class ReConstructBinaryTree {
public static void main(String[] args) {
int[] pre = {
1,2,4,7,3,5,6,8};
int[] in = {
4,7,2,1,5,3,6,8};
TreeNode treeNode = reConstructBinaryTree(pre, in);
prePost(treeNode);
}
/**
*
* @param pre 先序遍历序列
* @param in 中序遍历序列
* @return
*/
public static TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre.length == 0 || in.length == 0)
return null;
TreeNode root = new TreeNode(pre[0]);
for (int i = 0; i < in.length; i++) {
if(in[i] == pre[0]){
//左子树,copyOfRange函数是左闭右开
root.left = reConstructBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(in,0,i));
//递归构建左子树
root.right = reConstructBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length),Arrays.copyOfRange(in,i+1,in.length));
break;
}
}
return root;
}
/**
* 对构建的树进行先序遍历,验证结果
* @param root
*/
public static void prePost(TreeNode root){
if(root == null)
System.out.println("空树");
System.out.println(root.val);
if(root.left != null)
prePost(root.left);
if(root.right!= null)
prePost(root.right);
}
}
まとめ
この種のアルゴリズム問題は主に二分木の構造と性質を調べる問題であり、二分木の 3 つの走査規則を熟達する必要があると同時に、木の定義が再帰的であることを理解する必要があります。したがって、この種の問題を解決するには再帰が使用されます。