6 二叉搜索树
6.1 二叉搜索树定义
二叉搜索树有数值,「二叉搜索树是一个有序树」。
-
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
-
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
-
它的左、右子树也分别为二叉排序树
6.2 二叉搜索树典型题目
6.2.1 700. 二叉搜索树中的搜索
解法一:递归解法
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if(root==null || root.val==val) return root;
if(root.val>val){
return searchBST(root.left,val);
}
if(root.val<val){
return searchBST(root.right,val);
}
return null;
}
}
解法二:迭代解法
对于二叉搜索树可就不一样了,因为二叉搜索树的特殊性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。
对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。
而「对于二叉搜索树,不需要回溯的过程,因为节点的有序性就帮我们确定了搜索的方向。」
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
while(root!=null){
if(root.val<val){
root = root.right;
}else if(root.val>val){
root = root.left;
}else{
return root;
}
}
return null;
}
}
6.2.2 98. 验证二叉搜索树
解法一:
先递归中序遍历将二叉搜索树转变成一个数组。
扫描二维码关注公众号,回复:
13119047 查看本文章

然后只要比较一下,这个数组是否是有序的,「注意二叉搜索树中不能有重复元素」
class Solution {
List<Integer> res = new ArrayList<>();
public boolean isValidBST(TreeNode root) {
helper(root);
for(int i=1;i<res.size();i++){
if(res.get(i)<=res.get(i-1)) return false;
}
return true;
}
public void helper(TreeNode node){
if(node==null) return;
helper(node.left);
res.add(node.val);
helper(node.right);
}
}
解法二:
需要注意:「不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了」。
我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点。
class Solution {
public long maxvalue = Long.MIN_VALUE;
public boolean isValidBST(TreeNode root) {
if(root==null) return true;
boolean left = isValidBST(root.left);
if(maxvalue>=root.val){
return false;
}
maxvalue = root.val;
boolean right = isValidBST(root.right);
return left&&right;
}
}
解法三:
左子树范围的最小值是minVal,最大值是当前节点的值,也就是root的值,因为左子树的值要比当前节点小
右子数范围的最大值是maxVal,最小值是当前节点的值,也就是root的值,因为右子树的值要比当前节点大
class Solution {
public boolean isValidBST(TreeNode root) {
return getInfo(root,Long.MIN_VALUE,Long.MAX_VALUE);
}
public boolean getInfo(TreeNode root,long minval,long maxval){
if(root==null) return true;
if(root.val<=minval || root.val>=maxval) return false;
return getInfo(root.left,minval,root.val)&&getInfo(root.right,root.val,maxval);
}
}
6.2.3 530. 二叉搜索树的最小绝对差
题目中要求在二叉搜索树上任意两节点的差的绝对值的最小值。
「二叉搜索树」是有序的。
遇到在二叉搜索树上求最值、差值之类的,可以理解为在一个有序数组上求最值,求差值,这样就简单多了。
解法一:
最直观的想法,就是把二叉搜索树转换成有序数组,然后遍历一遍数组,就统计出来最小差值了。
class Solution {
List<Integer> tmp = new ArrayList<>();
public int getMinimumDifference(TreeNode root) {
transfer(root);
int res = Integer.MAX_VALUE;
for(int i=1;i<tmp.size();i++){
int num = Math.abs(tmp.get(i)-tmp.get(i-1));
if(num<res) res = num;
}
return res;
}
public void transfer(TreeNode node){
if(node==null) return;
transfer(node.left);
tmp.add(node.val);
transfer(node.right);
}
}
解法二:
在解法一的基础上,不需要使用数组进行比对。记录下前一个节点就可以了。
class Solution {
TreeNode pre ;
int res = Integer.MAX_VALUE;
public int getMinimumDifference(TreeNode root) {
transfer2(root);
return res;
}
public void transfer2(TreeNode node){
if(node==null) return;
transfer2(node.left);
if(pre!=null){
res = Math.min(Math.abs(pre.val-node.val),res);
}
pre = node;
transfer2(node.right);
}