二叉搜索树的性质:
根节点左侧的节点值都小于当前节点的值,根节点右侧节点值都大于当前节点的值。
所以二叉搜索树的中序遍历结果就是排序好的数组
所以大多二叉搜索树的题都可以用中序遍历来做。
题目1:
给你一个整数数组 nums
,其中元素已经按 升序 排列,请你将其转换为一棵 平衡 二叉搜索树。
class Solution {
public:
TreeNode* sortedArray(vector<int>& nums,int l,int r){
//建树,每次都拿中点位置当作二叉搜索树的根
if(l>r) return nullptr;
//以当前的中点当作当前的根
int mid = (l+r)/2;
TreeNode* root = new TreeNode(nums[mid]);//这是当前的根
//找他的左右根
TreeNode *ll = sortedArray(nums,l,mid-1);
TreeNode *rr = sortedArray(nums,mid+1,r);
root->left = ll;
root->right = rr;
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return sortedArray(nums,0,nums.size()-1);
}
};
题目2:
给你一个二叉树的根节点 root
,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
-
节点的左
子树
只包含
小于
当前节点的数。
-
节点的右子树只包含 大于 当前节点的数。
-
所有左子树和右子树自身必须也是二叉搜索树。
这个也可以用中序遍历来判断。
以下是题解做法,每次都传当前可以满足的最大和最小值,返回的bool值,判断是否满足条件(我之前使用的找每个节点左侧的最大值和右侧的最小值,然后再遍历一遍看是否满足条件,以下,可以过,但比较难写并且时间复杂度高)
class Solution {
public:
bool helper(TreeNode* root, long long lower, long long upper){
//判断当前root值是否满足lower到upper的区间
if(root->val>=upper||root->val<=lower){
return false;
}
if(root->left){
bool v = helper(root->left,lower,root->val);//对于左边要满足小于root.val
if(!v) return false;
}
if(root->right){
bool v = helper(root->right,root->val,upper);
if(!v) return false;
}
return true;
}
bool isValidBST(TreeNode* root) {
return helper(root, LONG_MIN, LONG_MAX);
}
};
题目3:
230. 二叉搜索树中第 K 小的元素 - 力扣(LeetCode)
这个就直接使用中序遍历就可以得到第k个值就是答案
lass Solution {
public:
int now;
int kthSmallest(TreeNode* root, int k) { //第k小的元素,找到原数组,就可以得到第k个值了
//变量方式是左根右的方式,按照这个顺序找
int ans=-1;
if(root->left){
int v = kthSmallest(root->left,k);
if(v!=-1){
return v;
}
}
now++;
if(now==k){
return root->val;
}
if(root->right){
int v = kthSmallest(root->right,k);
if(v!=-1){
return v;
}
}
return ans;
}
};