重建二叉树是剑指offer的原题:
这道题的实现原理我就不赘述了,网上非常多,自己自行查看。
话不多说直接上代码:
import java.util.LinkedList;
public class RebuildBinaryTree {
int preindex = 0;
int inindex = 0;
public TreeNode buildTree(int[] preorder, int[] inorder) {
return dfs(preorder, inorder, null);
}
//重建二叉树的核心代码
private TreeNode dfs(int[] preorder, int[] inorder, TreeNode finish) {
if(preindex == preorder.length || (finish != null && inorder[inindex] == finish.val))
return null;
TreeNode root = new TreeNode(preorder[preindex++]);
root.left = dfs(preorder, inorder, root);
inindex++;
root.right = dfs(preorder, inorder, finish);
return root;
}
//利用队列进行层序遍历,并打印重建好的二叉树
public void levelTraverse(TreeNode root) {
//判断二叉树是否为空
if (root == null) {
return;
}
LinkedList<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
System.out.print(node.val+" ");
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
}
public static void main(String[] agrs) {
int[] preorder = {
3,9,20,15,7};
int[] inorder = {
9,3,15,20,7};
// int[] preorder = {1,2,3};
// int[] inorder = {2,1,3};
// int[] preorder = {1,2,4,5,3,6,7};
// int[] inorder = {4,2,5,1,6,3,7};
RebuildBinaryTree bt = new RebuildBinaryTree();
TreeNode root = bt.buildTree(preorder, inorder);
bt.levelTraverse(root);
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x){
val = x;
}
}
发现没?重建二叉树的核心代码非常简短,就是一个递归函数。代码简洁是简洁,但是不是很难理解?自己当时在网上看到这段代码时,感觉是真的妙!但仔细一分析,对形参finish是真的迷,有时候有实参传给finish,有时候却没有。
后来自己用两层二叉树来仔细分析。自己把所有的递归函数嵌套起来,全部写详细,由最里层一层一层的往外分析。后来终于弄清楚finish了。
分析代码:
//此段代码不能正常运行,纯粹是用来分析上一段代码的实现原理
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x){
val = x;
}
}
public class Test {
//用来分析的数据
int[] preorder = {
1,2,3};
int[] inorder = {
2,1,3};
int preindex = 0;
int inindex = 0;
dfs(preorder, inorder, null){
//此时preindex为0,finish为null,不满足if的条件
if(preindex == preorder.length || (finish != null && inorder[inindex] == finish.val))
return null;
TreeNode root = new TreeNode(preorder[preindex++]);
//此时root是值为1的TreeNode,preindex为1
root.left = dfs(preorder, inorder, root){
//此时preindex为1,finish是值为1的TreeNode,
//由于inindex为0,inorder[inindex]为2,不满足if的条件
if(preindex == preorder.length || (finish != null && inorder[inindex] == finish.val))
return null;
TreeNode root = new TreeNode(preorder[preindex++]);
//此时root是值为2的TreeNode,preindex为2
root.left = dfs(preorder, inorder, root){
//此时preindex为2,finish是值为2的TreeNode,
//由于inindex为0,inorder[inindex]为2,满足if的条件,返回null
if(preindex == preorder.length || (finish != null && inorder[inindex] == finish.val))
return null;
TreeNode root = new TreeNode(preorder[preindex++]);
root.left = dfs(preorder, inorder, root);
inindex++;
root.right = dfs(preorder, inorder, finish);
return root;
}
inindex++;
//此时inindex为1
root.right = dfs(preorder, inorder, finish){
//此时preindex为2,由于它的上一级dfs函数中finish是值为1的TreeNode,所以它的finish也是值为1的TreeNode
//由于inindex为1,inorder[inindex]为1,满足if的条件,返回null
if(preindex == preorder.length || (finish != null && inorder[inindex] == finish.val))
return null;
TreeNode root = new TreeNode(preorder[preindex++]);
root.left = dfs(preorder, inorder, root);
inindex++;
root.right = dfs(preorder, inorder, finish);
return root;
}
return root;
}
inindex++;
//此时inindex为2
root.right = dfs(preorder, inorder, finish){
//此时preindex为2,由于它的上一级dfs函数中finish是值为null,所以它的finish也是null,不满足if条件
if(preindex == preorder.length || (finish != null && inorder[inindex] == finish.val))
return null;
TreeNode root = new TreeNode(preorder[preindex++]);
//此时root是值为3的TreeNode,preindex为3
root.left = dfs(preorder, inorder, root){
//此时preindex为3,finish是值为3的TreeNode,
//preorder.length也为3,满足if的条件,返回null
if(preindex == preorder.length || (finish != null && inorder[inindex] == finish.val))
return null;
TreeNode root = new TreeNode(preorder[preindex++]);
root.left = dfs(preorder, inorder, root);
inindex++;
root.right = dfs(preorder, inorder, finish);
return root;
}
inindex++;
//此时inindex为3
root.right = dfs(preorder, inorder, finish){
//此时preindex为3,由于它的上一级dfs函数中finish是值为null,所以它的finish也是null
//preorder.length也为3,满足if的条件,返回null
if(preindex == preorder.length || (finish != null && inorder[inindex] == finish.val))
return null;
TreeNode root = new TreeNode(preorder[preindex++]);
root.left = dfs(preorder, inorder, root);
inindex++;
root.right = dfs(preorder, inorder, finish);
return root;
}
return root;
}
return root;
}
}
虽然递归函数的实现原理是清楚了,但感觉还不是很懂。希望有高人指点!
感谢你的阅读!!!