# 什么是二叉搜索树
满足以下任意条件的树就是二叉搜索树:
- 是一颗空树
- 由根节点、左子树、右子树组成,并且左子树右子树都是二叉搜索树。且左子树上所有结点的数据域都小于等于根结点的数据域,右子树上所有结点的数据域都大于等于根结点的数据域。
二叉搜索树强调数据域的有序性,每一个颗子树都要满足 左孩子 <= 根节点 <= 右孩子。示例:
4
/
3
/
2
5
/ \
2 7
\
3
6
/ \
3 8
/ \ / \
1 4 7 9
二叉树的中序遍历是有序的。
const root = {
val: 6,
left: {
val: 3,
left: {
val: 1
},
right: {
val: 4
}
},
right: {
val: 8,
left: {
val: 7
},
right: {
val: 9
}
}
};
function inorder(root) {
if (!root) return root;
inorder(root.left);
console.log(root.val);
inorder(root.right);
return root;
}
inorder(root);
/*
1
3
4
6
7
8
9
*/
# 二叉搜索树基本操作
# 查找某一特定的值
const root = {
val: 6,
left: {
val: 3,
left: {
val: 1
},
right: {
val: 4
}
},
right: {
val: 8,
left: {
val: 7
},
right: {
val: 9
}
}
}
function search(root, n) {
let target = null;
if (!root) return root;
if (root.val === n) {
target = root.val;
}else if(root.val > n) {
target = search(root.left, n);
}else {
target = search(root.right, n);
}
return target;
}
# 插入新节点
const root = {
val: 6,
left: {
val: 3,
left: {
val: 1
},
right: {
val: 4
}
},
right: {
val: 8,
left: {
val: 7
},
right: {
val: 9
}
}
}
function insert(root, n) {
if (!root) {
root = new TreeNode(n);
return root;
}
if (root.val > n) {
root.left = insert(root.left, n);
}else {
root.right = insert(root.right, n);
}
return root;
}
function TreeNode(val) {
this.val = val;
this.left = this.right = null;
}
# 删除某一节点
function deleteNode(root, key) {
if (!root) return null;
if (root.val === key) {
if (!root.left) return root.right;
if (!root.right) return root.left;
let node = root.right;
while (node.left) {
node = node.left;
}
node.left = root.left;
root = root.right;
}else if (root.val > key) {
root.left = deleteNode(root.left, key);
}else {
root.right = deleteNode(root.right, key);
}
return root;
}
# 二叉搜索树的验证
题目描述:给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:
2
/ \
1 3
输出: true
示例 2:
5
/ \
1 4
/ \
3 6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4 。
方法一:
const isValidBST = function(root) {
function dfs(root, minValue, maxValue) {
if !(root) {
return true;
}
if (root.val <= minValue || root.val >= maxValue) return false;
return dfs(root.left, minValue, root.val) && dfs(root.right, root.val, maxValue)
}
return dfs(root, -Infinity, Infinity)
}
方法二:
var isValidBST = function (root) {
let minValue = -Infinity;
function inorder(root) {
if (!root) return true;
if (!inorder(root.left)) return false;
if (root.val <= minValue) return false;
minValue = root.val;
return inorder(root.right);
}
return inorder(root);
};
# 将排序数组转为二叉搜索树
题目描述:将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定有序数组: [-10,-3,0,5,9],
一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
方式一:
var sortedArrayToBST = function (nums) {
const root = buildBST(nums);
function buildBST(nums) {
const len = nums.length;
if (!len) return null;
const mid = Math.floor(len / 2);
const cur = new TreeNode(nums[mid]);
cur.left = buildBST(nums.slice(0, mid))
cur.right = buildBST(nums.slice(mid + 1));
return cur;
}
return root;
};
function TreeNode(val) {
this.val = val;
this.left = this.right = null;
}
方式二:
var sortedArrayToBST = function (nums) {
const root = buildBST(0, nums.length - 1);
function buildBST(low, high) {
if (low > high) return null;
const mid = Math.floor((low + high) / 2);
const cur = new TreeNode(nums[mid]);
cur.left = buildBST(low, mid - 1);
cur.right = buildBST(mid + 1, high);
return cur;
}
return root;
};