二叉查找树(Binary Search Tree)
- 二叉搜索树
- 快速查找,插入,删除
- 定义:每个节点,都不大于它的右子节点,且不小于它的左子节点
- 查找:递归:大找右边,小找左边,找到或没了返回
- 插入:递归:大找右空,不空往右;小找左空,不空往左
- 删除
- 先找,并记录父节点
- 无子节点,父节点指向null
- 一个子节点,父节点指向它
- 2个子节点,替换和删除(右侧最小节点)
- 排序:中序遍历,复杂度O(n),二叉排序树
- 数据重复二叉树
- 复杂度分析:
- 二叉树退化成链表:O(n)
- 平衡二叉树:O(logn),增删查
- 对比散列表
- 排序优势
- 散列表存在扩容、散列冲突等,导致性能问题。平衡二叉树稳定,常用
- 散列表较复杂,例如:散列函数设计,扩容,缩容,散列因子等
function inOrder(root) {
let str = ''
fn(root)
console.log(str)
function fn(root) {
if (!root) return
fn(root.left)
str += ' ' + root.data
fn(root.right)
}
}
class Node {
constructor(data) {
this.data = data
this.left = null
this.right = null
}
}
function insert(tree, data) {
if (!tree) {
return new Node(data)
}
let p = tree
while (tree) {
if (data >= p.data) {
if (p.right) {
p = p.right
} else {
p.right = new Node(data)
return
}
} else {
if (p.left) {
p = p.left
} else {
p.left = new Node(data)
return
}
}
}
}
function find(tree, data) {
while (tree) {
if (data < tree.data) {
tree = tree.left
} else if (data > tree.data) {
tree = tree.right
} else {
return tree
}
}
return null
}
function del(tree, data) {
let pp
let p = tree
while (p && p.data != data) {
pp = p
if (data > p.data) {
p = p.right
} else {
p = p.left
}
}
if (!p) return
if (p.left && p.right) {
let minP = p.right
let minPP = p
while (minP.left) {
minPP = minP
minP = minP.left
}
p.data = minP.data
p = minP
pp = minPP
}
let child = p.left || p.right || null
if (!pp) {
tree = child
} else if (pp.left == p) {
pp.left = child
} else {
pp.right = child
}
del(tree, data)
}
let tree = insert(null, 5)
insert(tree, 6)
insert(tree, 7)
insert(tree, 3)
insert(tree, 4)
insert(tree, 2)
insert(tree, 2)
insert(tree, 1)
insert(tree, 9)
insert(tree, 9)
inOrder(tree)
del(tree, 2)
del(tree, 9)
inOrder(tree)
insert(tree, 9)
- 根节点高度
- 递归:max(子树高度列表)+1
- 队列:层次遍历,判断每层是否都完成出队
function maxDepth(tree) {
if (!tree) return 0
return Math.max(maxDepth(tree.left), maxDepth(tree.right)) + 1
}
function maxDepth1(tree) {
if (!tree) return 0
let queue = [tree]
let front = 0
let rear = queue.length
let floor = 0
while (queue.length) {
let node = queue.shift()
front++
if (node.left) {
queue.push(node.left)
}
if (node.right) {
queue.push(node.right)
}
if (front == rear) {
front = 0
rear = queue.length
floor++
}
}
return floor
}
console.log(maxDepth(tree))
console.log(maxDepth1(tree))