function BinarySearchTree() {
//根节点
this.root = null
function Node(key) {
this.key = key
this.left = null
this.right = null
}
//插入
BinarySearchTree.prototype.insert = function (key) {
//创建新的节点
var newNode = new Node(key)
//判断是否存在根节点
if (!this.root) {
//如果不存在根节点
this.root = newNode
} else {
this.insertNode(this.root, newNode)
}
}
//递归进行节点插入
BinarySearchTree.prototype.insertNode = function (node, newNode) {
if (node.key > newNode.key) {
//如果新插入的节点的值小于当前节点的值,就判断当前节点的左边是否有节点,如果有继续比较,如果没有则直接插入
if (node.left == null) {
node.left = newNode
} else {
this.insertNode(node.left, newNode)
}
} else {
//如果新插入的节点的值大于当前节点的值,就判断当前节点的右边是否有节点,如果有继续比较,如果没有则直接插入
if (node.right == null) {
node.right = newNode
} else {
this.insertNode(node.right, newNode)
}
}
}
//前序遍历
BinarySearchTree.prototype.prevOrderTraversal = function (handler) {
this.prevOrderTraversalNode(this.root, handler)
}
//前序遍历节点
BinarySearchTree.prototype.prevOrderTraversalNode = function (node, handler) {
if (node != null) {
handler(node.key)
//先遍历左边的节点,直到左边没有节点了返回上一层,查看右边是否有节点,如果没有就再返回上层,直到遍历完所有元素
this.prevOrderTraversalNode(node.left, handler)
this.prevOrderTraversalNode(node.right, handler)
}
}
//中序遍历
BinarySearchTree.prototype.middleOrderTraversal = function (handler) {
this.middleOrderTraversalNode(this.root, handler)
}
//中序遍历节点
BinarySearchTree.prototype.middleOrderTraversalNode = function (node, handler) {
if (node != null) {
this.middleOrderTraversalNode(node.left, handler)
handler(node.key)
this.middleOrderTraversalNode(node.right, handler)
}
}
//后序遍历
BinarySearchTree.prototype.behindOrderTraversal = function (handler) {
this.behindOrderTraversalNode(this.root, handler)
}
BinarySearchTree.prototype.behindOrderTraversalNode = function (node, handler) {
if (node != null) {
this.behindOrderTraversalNode(node.left, handler)
this.behindOrderTraversalNode(node.right, handler)
handler(node.key)
}
}
//最大值
BinarySearchTree.prototype.maxValue = function () {
var current = this.root
while (current.right) {
current = current.right
}
return current.key
}
//最小值
BinarySearchTree.prototype.minValue = function () {
var current = this.root
while (current.left) {
current = current.left
}
return current.key
}
//搜索
BinarySearchTree.prototype.search = function (key) {
var node = this.root
while (node) {
if (key < node.key) {
node = node.left
} else if (key > node.key) {
node = node.right
} else {
return true
}
}
return false
}
//删除
BinarySearchTree.prototype.delete = function (key) {
var node = this.root
//初始化父节点
var parentNode = null
//判断被删除节点是其父节点左节点还是右节点
var isLeftNode = true
while (node.key != key) {
//当查找的节点小于当前节点时向左查找
if (key < node.key) {
//给要删除节点的父节点重新赋值
parentNode = node
node = node.left
isLeftNode = true
//当查找的节点大于当前的节点是向右查找
} else if (key > node.key) {
parentNode = node
node = node.right
isLeftNode = false
}
if (node == null) return false
}
//被删除的节点没有左节点 也没有右节点
if (!node.left && !node.right) {
//当前节点为根节点时
if (node == this.root) {
this.root = null
return true
} else {
if (isLeftNode) {
parentNode.left = null
return true
} else {
parentNode.right = null
return true
}
}
}
//被删除的节点有左节点或者是右节点
else if ((node.left && !node.right) || (!node.left && node.right)) {
//被删除的元素有左节点
if (node == this.root) {
//当删除的节点为根节点时
if (node.left) {
this.root = node.left
} else {
this.root = node.right
}
} else {
if (isLeftNode) {
if (node.left) {
parentNode.left = node.left
} else {
parentNode.left = node.right
}
} else {
if (node.left) {
parentNode.right = node.left
} else {
parentNode.right = node.right
}
}
}
}
//被删除的节点两边都有节点,需要找被删除的节点的前驱和后继 前驱:左边节点里最大的节点 后继:右边节点里最小的节点
else {
var successor = this.getSuccessor(node)
if (node == this.root) {
this.root = successor
} else {
if (isLeftNode) {
parentNode.left = successor
} else {
parentNode.right = successor
}
}
//把被删除的节点的左子树转接给后继节点的左子节点
successor.left = node.left
}
}
//寻找当前节点的后继
BinarySearchTree.prototype.getSuccessor = function (node) {
//被删除节点
var delNode = node
//后继的父节点
var delNodeRight = node.right
//后继节点
var successor = node.right
while (successor.left) {
delNodeRight = successor
successor = successor.left
}
//当后继节点 有右子节点时
delNodeRight.left = successor.right
successor.right = delNode.right
return successor
}
}