二叉搜索树的定义:何为二叉搜索树满足根节点的值大于其左孩子节点的值,根节点的值又小于其右孩子节点的值
其他的就没什么好说的了,下面会不断更新二叉搜索树的相关题目:
例题一:给定一个有序整数数组,元素各不相同且按升序排列,编写一个算法,创建一棵高度最小的二叉搜索树。(力扣:面试题 04.02. 最小高度树)
//利用递归生成二叉搜索树:基本思路就是不断将数组分成左右两边然后左边和右边的数组分别递归
//这题我不会纯粹是看了题解才做出来的,我甚至没有一点点思路
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return creatTree(nums,0,nums.length-1);
}
public TreeNode creatTree(int[] nums,int left,int right) {
//递归的出口
if(left>right){
return null;
}
int mid=(left+right)/2;
TreeNode root=new TreeNode(nums[mid]);
//注意每次递归left以及right的范围
root.left=creatTree(nums,left,mid-1);
root.right=creatTree(nums,mid+1,right);
return root;
}
}
其实怎麽一道题又一种自可意会不可言传的感觉,建议你照着代码思路走一遍
例题2:给你一个整数 n ,请你生成并返回所有由 n 个节点组成且节点值从 1 到 n 互不相同的不同 二叉搜索树 。可以按 任意顺序 返回答案。(力扣:95)
class Solution {
public List<TreeNode> generateTrees(int n) {
return creatTree(1,n);
}
public List<TreeNode> creatTree(int start,int end){
//创建一个集合用于存储每个二叉树的节点,为什麽要定义为局部变量.而且为什么要放在这个地方,是因为他最后返回的是递
//归 第一层,也就是包含所有的节点的二叉树,同时将七设为局部变量的原因是它的每一层递归都需要保存
List <TreeNode> list=new ArrayList<TreeNode>();
//如果left<right的话,说明该子树没有一个节点但你依旧要添加一个空节点过去为什么,因为要方便后面的节点组合
if(start>end){
list.add(null);
return list;
}
for(int i=start;i<=end;i++){
//在该i的左边再次调用递归,获取所有左子树的集合
List <TreeNode> left=creatTree(start,i-1);
List <TreeNode> right=creatTree(i+1,end);
//将该i形成的根节点与左右子树排列组合形成一颗新的树
for(TreeNode l:left){
for(TreeNode r:right){
TreeNode root=new TreeNode(i);
root.left=l;
root.right=r;
list.add(root);
}
}
}
return list;
}
}
理解1:理解这道题其实是生成最小平衡二叉树的加强版,加强的地方在哪里呢?本来生成最小平行二叉树是加某个数组均分为左右两边,然后,再在左右两边不断递归直到left>right为止,可是这道题呢,生成树思路与生成平衡二叉树的思路大致是一样的,但是他并不是均分,它是将左边的个数从0不断增加,右边的个数从零个不断减少,而且对于左右两边个数不同的每一种情况,他都要进行排列组合
理解2:首先是这道题递归的理解,这道题给我递归的感觉就类似于汉诺塔问题,它用的的递归思想就是大的问题转化为小的问题,补取追求它的细节,我们之前所做的递归的题目大多可以理解它的细节,而这个似乎只能理解其大概的思路,还有的到题的局部变量的返回值也十分关键