以 leetcode 上常见的一些题为例进行说明。
二叉搜索树的操作同样也与树的遍历方式息息相关,不了解的可以参考我的上上篇博客。
判断是否是二叉搜索树
首先想到只要遍历每个节点,判断左子小于。右子大于,即可,但是发现只满足这两个调价你的不一定的二叉搜索树,比如这棵树 [10,5,15,null,null,6,20],其实还需要加一个条件,就是不仅仅要左子小于。右子大于,是整个左子树小于,整个右子树大于,看上去比较烦。我们换一种思路。
我们知道中序遍历的过程就是二叉搜索树升序遍历的过程,每遍历到一个点与上一个点进行比较,并将其值保存,用于与下一个节点比较 。
var isValidBST = function(root) {
//中序遍历,记录前一个值
if(!root) return true
let stack = []
let pre = -Infinity
let current = root
while(stack.length > 0 || current){
while(current){
stack.push(current)
current = current.left
}
current = stack.pop()
if(current.val <= pre){
return false
}else{
pre = current.val
}
current = current.right
}
return true
};
修剪二叉搜索树
要求是将树的最大值与最小值修剪刀到给定范围内。
注意:如果某个节点不在给定范围内,不是直接砍掉,而是将其下修剪完的接到该节点的位置上!
类递归前序实现,
var trimBST = function(root, L, R) {
if(!root) return root
if(root.val > R) return trimBST(root.left, L, R)
if(root.val < L) return trimBST(root.right, L, R)
root.left = trimBST(root.left, L, R)
root.right = trimBST(root.right, L, R)
return root
};
把二叉搜索树转换为累加树
使得每个节点的值是原来的节点值加上所有大于它的节点值之和。
中序遍历是升序遍历的过程,我们需要用到反中序遍历,使得遍历到的值是降序的,同时对值进行累加。
var convertBST = function(root) {
//使用反中序遍历,右中左 是从大到小的顺序
let sum = 0
function help(root){
if(!root) return root
help(root.right)
sum += root.val
root.val = sum
help(root.left)
}
help(root)
return root
};