(1)15 15 15 15
/ \ / \ / \ / \
9 23 ==> (1)9 23 ==> 9 23 ===> 9 23
/ \ / \ / \ / \ / \ / \ / \ / \
3 12 17 28 3 12 17 28 (1)3 12 17 28 3 12 17 28
\ \ \ / \
8 8 8 1 8
插入的时间复杂度:O(logn)
const insert = (root, value) => {
const newNode = { val: value, left: null, right: null }
if (!root) {
return newNode
let node = root
while(node) {
if (value > node.val) {
if (!node.right) {
node.right = newNode
return
} else {
node = node.right
} else {
if (!node.left) {
node.left = newNode
return
} else {
node = node.left
return root
二叉搜索树删除
删除节点node 流程:
叶子节点,直接删除,把node的parent对于node的指向置空
只有一个子节点child,则删除node,然后把子节点child作为新的跟节点,即把node的parent对于node的指向改为child
1 1 1
/ ==> 删除节点2 ==> / ==> 节点3替换 ==> /
2 x 3
/ / / \
3 3 4 5
/ \ / \
4 5 4 5
删除的节点有左节点和右节点,则删除节点node,然后node的左子树的最大值,就是node的左子树的最右子节点pNode(一路向右),然后把pNode的值作为node的新值,删除的转移成删除pNode
15 15
/ \ / \
9 23 9 23
/ \ ===> 删除节点9 ===> 找到左子树最大值4 ==> / \ ===>
3 12 17 3 12 17
/ \ / \
1 4 1 (4)
==> 替换9变成4,然后删除4
4 23
3 12 17
删除的时间复杂度:O(logn)
const del = (root, value) => {
let parent = null
let node = root
while(node && node.val !== value) {
parent = node
if (value > node.val) {
node = node.right
} else {
node = node.left
if (!node) {
return root
if (node.left && node.right) {
const temp = node
parent = node
node = node.left
while(node.right) {
parent = node
node = node.right
temp.val = node.val
const child = node.left || node.right
if (!parent) {
return child
if (parent.left === node) {
parent.node = child
} else {
parent.right = child
二叉搜索树的查找
查找流程:
从根节点开始比较,大于则往右子树查找,小于往左子树查找
查找的平均时间复杂度是树高 O(logn)
const find = (root, target) => {
let node = root
while(node && node.val !== target) {
if (target > node.val) {
node = node.right
} else {
node = node.left
return !!(node && node.val === target)
最佳二叉搜索树
二叉搜索树查找的时间复杂度是树高,平均复杂度是O(logn),但是当最大值或者最小值作为树根的时候,树的高度会变成n,远大于平均复杂度,因此尽可能的平均左右子树的节点树,可以有效的降低树高。
让中位数做树的根节点
代码实现从1~n的节点构建一个最佳二叉树
const createBestBinarySearchTree = (start, end) => {
if (start > end) {
return null
const mid = Math.floor((start + end) / 2)
const root = { val: mid, left: null, right: null }
root.left = createBestBinarySearchTree(start, mid - 1)
root.right = createBestBinarySearchTree(mid + 1, end)
return root
平衡二叉搜索树
对于最佳二叉搜索树进行多次的插入和删除后,会变成非最佳二叉排序树,因为随着插入和删除,树根可能不是中位数了,相最大/最小偏移,影响查找速度,因此要动态的保持查找效率,需要利用平衡二叉树,也就是平衡二叉搜索树