一、题目
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
示例1
输入
复制
[1,2,3,4,5,6,7],[3,2,4,1,6,5,7]
返回值
复制
{1,2,5,3,4,6,7}
法一:递归,JAVA,数组
思路:递归过程,通过前序数组找到二叉树的根结点,再通过中序数组分出二叉树的左右子树,重复该过程直到数组没有元素
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
//法一:递归,数组
public class Solution {
public int[] copyOfrange(int []array,int from,int to)
{
int[] result=new int[to-from];
for(int i=from,j=0;i<to;i++,j++)
result[j]=array[i];
return result;
}
public 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(pre[0]==in[i])
{
//java自带函数Array.copyOfrange,需要包import java.util.Arrays;
//root.left=reConstructBinaryTree(Array.copyOfrange(pre,1,i+1),Array.copyOfrange(in,0,i));
//root.right=reConstructBinaryTree(Array.copyOfrange(pre,i+1,pre.length),Array.copyOfrange(in,i+1,in.length));
//自己写的数组复制函数
root.left=reConstructBinaryTree(copyOfrange(pre,1,i+1),copyOfrange(in,0,i));
root.right=reConstructBinaryTree(copyOfrange(pre,i+1,pre.length),copyOfrange(in,i+1,in.length));
}
}
return root;
}
}
法二:递归,JAVA,List
//重建二叉树,法二:递归,List
public static TreeNode Tree(List<int> preTree,List <int>midTree)
{
if(preTree==null||preTree.Count==0||midTree==null||midTree.Count==0)
return null;
int i=1;
//根结点
int rootTree=preTree[0];
//移除根结点
preTree.RemoveAt(0);
//新建结点存储当前值,并指向左右子树
TreeNode treeNode=new TreeNode(rootTree);
//左右子树
List<int> midLeft=null;
List<int> tempMid=new AarrayList<int>();//中序遍历左右子树
List<int> preLeft=null;
List<int> tempPre=new AarrayList<int>();//前序遍历左右子树
bool isTree=false;
foreach(var item in midTree)
{
tempMid.Add(item);
tempPre.Add(preTree[i++]);
if(item==rootTree)
{
//确认是一棵二叉树
isTree=true;
//左子树的中序遍历
midLeft=tempMid;
//中序遍历移除根结点
midTree.RemoveAt(item);
//新建临时结点,存储右子树
tempMid=new List<int>();
//左子树的前序遍历
preLeft=tempPre;
tempPre=new List<int>();
}
}
if(!isTree)
{
Console.WriteLine("不是正确的数");
return null;
}
List<int> midRight=tempMid;
List<int> preRight=tempPre;
//递归左右子树
treeNode.left=Tree(preLeft,midLeft);
treeNode.right=Tree(preRight,midRight);
}
二、二叉树操作
二叉树结构:
public class TreeNode
{
public int val;
public TreeNode left;
public TreeNode right;
TreeNode(int x)//构造函数
{
val=x;
}
}
前序遍历:根结点,左子树,右子树
public static void PreNode(TreeNode node,List<int> treeList)
{
if(node!=null)
{
treeList.Add(node.val);
PreNode(node.left,treeList);
PreNode(node.right,treeList);
}
}
中序遍历:左子树,根结点,右子树
public static void MidNode(TreeNode node,List<int> treeList)
{
if(node!=null)
{
MidNode(node.left,treeList);
treeList.Add(node.val);
MidNode(node.right,treeList);
}
}
后序遍历:左子树,右子树,根结点
public static void EndNode(TreeNode node,List<int> treeList)
{
if(node!=null)
{
EndNode(node.left,treeList);
EndNode(node.right,treeList);
treeList.Add(node.val);
}
}
层次遍历:借助一个队列,先将根结点入队,然后根结点出队,每个结点出队时就访问该结点,且若其子树不为空则将其子树入队,然后每一层从左往右进行入队,直到队空。
public static void LevelNode(TreeNode node,List<int> treeList)
{
if(node!=null)
{
Queue<int> queue=new Queue<TreeNode>();
queue.Enqueue(node);
TreeNode currentNode=null;
while(queue.Count>0)
{
currentNode=queue.Dequeue();
treeList.Add(currentNode.val);
if(currentNode.left!=null)
{
queue.Enqueue(currentNode.left);
}
if(currentNode.right!=null)
{
queue.Enqueue(currentNode.right);
}
}
}
}
感谢参考博客: