class Node {
constructor(value) {
this.value = value
this.left = null
this.right = null
}
}
class BST {
constructor() {
this.root = null
this.size = 0
}
getSize() {
return this.size
}
isEmpty() {
return this.size === 0
}
addNode(v) {
this.root = this._addChild(this.root, v)
}
//添加节点时需要比较添加的节点和当前的节点值的大小
_addChild(node, v) {
if (!node) {
this.size++
return new Node(v)
}
if (node.value > v) {
node.left = this._addChild(node.left, v)
} else if (node.value < v) {
node.right = this._addChild(node.right, v)
}
return node
}
}
//树的遍历 前中后序深度遍历
//先序遍历可用于打印树结构
function preTraversal() {
this._pre(this.root)
}
function _pre(node) {
if (node) {
console.log(node.value)
this._pre(node.left)
this._pre(node.right)
}
}
//中序遍历可用于排序 对于BST中序遍历一次就可以得到有序的值
function midTraversal() {
this._mid(this.root)
}
function _mid(node) {
if (node) {
this._mid(node.left)
console.log(node.value)
this._mid(node.right)
}
}
//后序遍历可用于先操作子节点,再操作父节点的场景
function backTraversal() {
this._back(this.root)
}
function _back(node) {
if (node) {
this._back(node.left)
this._back(node.right)
console.log(node.value)
}
}
//广度遍历 利用队列结构来完成
function breadthTraversal() {
if (!this.root) return null
let q = new Queue()
//根节点入队
q.enQueue(this.root)
//循环判断队列是否为空,为空则树遍历完毕
while (!q.isEmpty()) {
let n = q.deQueue()
console.log(n.value)
if (n.left) q.enQueue(n.left)
if (n.right) q.enQueue(n.right)
}
}
function getMin() {
return this._getMin(this.root).value
}
function _getMin() {
if (!node.left) return node
return this._getMin(node.left)
}
function getMax() {
return this._getMax(this.root).value
}
function _getMax() {
if (!node.right) return node
return this._getMax(node.right)
}
//向下取整
function floor(v) {
let node = this._floor(this.root, v)
return node ? node.value : null
}
function _floor(node, v) {
if (!node) return null
if (node.value === v) return v
//若当前节点值比需要的值还大,继续递归
if (node.value > v) {
return this._floor(node.left, v)
}
let right = this._floor(node.right, v)
if (right) return right
return node
}
function select(k) {
let node = this._select(this.root, k)
return node ? node.value : null
}
function _select(node, k) {
if (!node) return null
//获取左子树下有几个节点
let size = node.left ? node.left.size : 0
//若size>k 代表所需要的节点在左子树
if (size > k) return this._select(node.left, k)
if (size < k) return this._select(node.right, k - size - 1)
return node
}
//删除节点
//有三种情况:要删除的节点有左右两条子树,只有一条子树和没有子树
//删除最小节点
function deleteMin() {
this.root = this._deleteMin(this.root)
console.log(this.root)
}
function _deleteMin(node) {
//一直递归左子树,若左子树为空,则判断节点是否有右子树,有的话把需要删除的节点替换为右子树
if ((node != null) & !node.left) {
return node.right
}
node.left = this._deleteMin(node.left)
node.size = this._getSize(node.left) + this._getSize(node.right) + 1
return node
}