重建二叉树
- 根据二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
创建的二叉树如下:
二叉树的创建一般有两中思路,递归和借助栈来存储节点,实用递归最简洁,但是使用栈最好理解
前序:根左右
中序:左根右
思路:分两步走:
1.确定是按先序,还是中序,还是后序创建二叉树
2.确定是当前节点要存储的元素
先来看看使用C语言来先序创建二叉树
Build(&T)
{
if(递归退出条件)
{
T=(TreeNode**)malloc(sizeof(TreeNode));
T->left=NULL;
T->right=NULL;
T->data=X;
}
else
{
Build(T->left)
Build(T->right);
}
}
这个过程在C语言版的数据结构里面很熟悉了,接下来要做的就是找到上方程序中的X;
大致思路:
preorder = [3,9,20,15,7]
- T=NULL
- inorder = [9,3,15,20,7]进入递归函数
当前:T->data=3(当前preorder序列的第一个就是),把当前inorder序列[9,3,15,20,7]从3这里分割,得到T->left的中序序列为[9],T->right的中序序列[15,20,7],
- T=T->left
- preorder=[9]
- inorder=[9]
当前,T->data=3(当前preorder序列的第二个就是),把当前inorder序列[9]从9这里分割,得到空,说明T是叶子节点了,跳出当前递归函数 - T=T->right
- -inorder=[15,20,7]进入递归函数
…
可以发现if的大括号应该怎么填呢???
其实应该是inorder不为空(因为为空说明到了叶子节点,不能继续往下创建节点),然后X的值其实就是按照先序序列依次取值
这样思路就明确了
package 二叉树的创建;
/*
* 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树,假设输入的前序遍历和中序遍历的结果中都不含重复的数字
* 例如给出
* 前序遍历 preorder=[3,9,20,15,7]
* 中序遍历 inorder=[9,3,15,20,7]
*
*/
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode(int x)
{
this.val=x;
this.left=null;
this.right=null;
}
public static void main(String[] args)
{
TreeNode Root=null;
Solution ss=new Solution();
int[] preorder={3,9,20,15,7};
int[] inorder={9,3,15,20,7};
Root=ss.buildTree(preorder,inorder);
}
}
class Solution {
public int preIndex = 0;
//在中序序列inorder[start~end]中,查找val的下标
public int find(int[] inorder, int start,int end,int val){
for(int i = start;i<=end;i++){
if(inorder[i] == val) return i;
}
return -1;
}
public TreeNode buildTreeChild(int[] preorder, int[] inorder, int inbegin,int inend) {
if(inbegin>inend) return null;
TreeNode root = new TreeNode(preorder[preIndex]);
int index = find(inorder,inbegin,inend,preorder[preIndex]);
if(index == -1) return null;
preIndex++;
root.left = buildTreeChild(preorder,inorder,inbegin,index-1);
root.right = buildTreeChild(preorder,inorder,index+1,inend);
return root;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder == null || inorder == null) return null;
return buildTreeChild(preorder,inorder,0,inorder.length-1);
}
}
双栈实现队列
思路:自定义一个队列类Q,该类有两个栈对象实例s1,s2
创建进队列方法:把要存储的元素依次入栈s1,再依次出栈,把出栈的元素依次入栈s2
创建出队列方法:把s2中的元素依次出栈即可