一、递归函数是否需要返回值
二叉树中,利用递归函数,能够快速的对算法题目进行求解,但递归函数是否需要返回值是一个很令人头疼的问题,对于该问题进行了总结:(一般情况下)
1、如果需要搜索整颗二叉树,那么递归函数就不要返回值了
2、如果要搜索其中一条符合条件的路径,递归函数就需要返回值,因为遇到符合条件的
路径就要及时返回。比如,返回boolean类型的值。
二、二叉树的构造
①通过后序和中序数组来构造二叉树
Step1:后序数组的最后一个元素,即为当前的根节点
step2:根据后序数组的最后一个元素对中序数组进行分割,分割为左右两个子数组。
step3:根据中序数组的左右两个子数组长度,对后序数组进行分割。
step4:通过递归函数进行循环,直到子数组长度小于1为止。
(这里的分割并不是新建一个数组进行元素存储,而是通过数组下标索引,直接在原数组上进行操作)
具体代码如下:
public TreeNode buildTree(int[] inorder, int[] postorder) {
return buildTree1(inorder, 0, inorder.length, postorder, 0, postorder.length);
}
public TreeNode buildTree1(int[] inorder,int inLeft,int inRight,int[] postorder,int postLeft,int postRight){
//第一步判断数组是否为空,如果为空则返回null
if(inRight -inLeft < 1) return null;
//如果长度为1,则直接返回
if(inRight -inLeft == 1) return new TreeNode(inorder[inLeft]);
//第二步找到后序数组的最后一个元素
int rootVal = postorder[postRight-1];
TreeNode root = new TreeNode(rootVal);
int mid ;
//第三步,根据后序数组的最后一个元素,对中序数组进行分割
for(mid = inLeft;mid<inRight;mid++){
if(inorder[mid] == rootVal){
break;
}
}
//对数组进行分割,递归
root.left = buildTree1(inorder,inLeft,mid,postorder,postLeft,postLeft+(mid-inLeft));
root.right = buildTree1(inorder,mid+1,inRight,postorder,postLeft+(mid-inLeft),postRight-1);
return root;
}
②通过前序和中序数组来构造二叉树
与①中的思路一致,只是是要通过前序数组的第一个元素来进行中序数组的子数组的划分,可直接在上述代码上进行修改。
③最大二叉树
给一个没有重复元素的数组,根据该数组进行二叉树的构建。
思路相似,在这里是要根据数组中的最大元素来对数组进行子数组分割。
给出如下代码:
public TreeNode constructMaximumBinaryTree(int[] nums) {
return buildTree(nums,0,nums.length);
//数组实际上没有被切割开,而是虚拟的被切割开
}
public TreeNode buildTree(int[] nums,int left,int right){
//如果数组为长度0,直接返回
if(right - left <1) return null;
//如果长度为1,则将该值添加进树中
if(right - left == 1) {
return new TreeNode(nums[left]);
}
TreeNode root = new TreeNode();
//找到数组中的最大值,做为根节点
int maxIndex=left; //从数组的最左边开始比较,不能为0,这样是不对的
int maxNumber = nums[maxIndex];
for(int i = left+1;i<right;i++){
if(nums[i]>nums[maxIndex]){
maxIndex = i;
}
}
maxNumber = nums[maxIndex];
root.val = maxNumber;
//根据最大元素进行划分
root.left = buildTree(nums,left,maxIndex);
root.right=buildTree(nums,maxIndex+1,right);
return root;
}