<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 封装二叉树类
function BinarySerachTree() {
// 节点类
function Node(key) {
this.key = key
this.left = null
this.right = null
}
// 属性
this.root = null //根节点
// 方法
// 插入数据:对外给用户调用
BinarySerachTree.prototype.insert = function (key) {
// 1.根据key创建节点
var newNode = new Node(key)
// 2.判断根节点是否有值
if (this.root == null) {
this.root = newNode
} else {
this.insertNode(this.root, newNode)
}
}
// 第一次: node->9 newNode->14
// 第二次: node->13 newNode->14
// 第四次: node->15 newNode->14
BinarySerachTree.prototype.insertNode = function (node, newNode) {
if (newNode.key < node.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)
}
}
}
// 树的遍历
// 1.先序遍历
BinarySerachTree.prototype.preOrderTraversal = function (handler) {
this.preOrderTraversalNode(this.root, handler)
}
// 第一次: node->11
// 第二次: node->7
// 第三次: node->5
BinarySerachTree.prototype.preOrderTraversalNode = function (node, handler) {
if (node != null) {
// 1.处理经过的节点
handler(node.key)
// 2.查找经过节点的左子节点
this.preOrderTraversalNode(node.left, handler)
// 3.查找经过节点的右子节点
this.preOrderTraversalNode(node.right, handler)
}
}
// 2.中序遍历
BinarySerachTree.prototype.midOrderTraversal = function (handler) {
this.midOrderTraversalNode(this.root, handler)
}
BinarySerachTree.prototype.midOrderTraversalNode = function (node, handler) {
if (node != null) {
// 1.查找左子树中的节点
this.midOrderTraversalNode(node.left, handler)
// 2.处理节点
handler(node.key)
// 3.查找右子树中的节点
this.midOrderTraversalNode(node.right, handler)
}
}
// 3.后序遍历
BinarySerachTree.prototype.postOrderTraversal = function (handler) {
this.postOrderTraversalNode(this.root, handler)
}
BinarySerachTree.prototype.postOrderTraversalNode = function (node, handler) {
if (node != null) {
// 1.查找左子树中的节点
this.postOrderTraversalNode(node.left, handler)
// 3.查找右子树中的节点
this.postOrderTraversalNode(node.right, handler)
// 2.处理节点
handler(node.key)
}
}
// 寻找最值
// 1.寻找最大值
BinarySerachTree.prototype.max = function () {
// 1.获取根节点
var node = this.root
// 2.依次向右不断查找,直到节点为null
var key = null
while (node != null) {
key = node.key
node = node.right
}
return key
}
// 2.寻找最小值
BinarySerachTree.prototype.min = function () {
// 1.获取根节点
var node = this.root
// 2.依次向左不断查找,直到节点为null
var key = null
while (node != null) {
key = node.key
node = node.left
}
return key
}
// 3.查询某个特定的值是否存在
BinarySerachTree.prototype.search = function (key) {
// 1.获取根节点
var node = this.root
// 2.循环搜索key
while (node != null) {
if (key < node.key) {
node = node.left
} else if (key > node.key) {
node = node.right
} else {
return true
}
}
// 循环结束返回false
return false
}
// 删除节点
BinarySerachTree.prototype.remove = function (key) {
// 1.寻找要删除的节点
// 1.1定义变量,保存一些信息
var current = this.root
var parent = null
var isLeftChild = true
// 1.2开始寻找删除的节点
while (current.key != key) {
parent = current
if (key < current.key) {
isLeftChild = true
current = current.left
} else {
isLeftChild = false
current = current.right
}
// 已经找到了最后的节点,依然没有找到==key
if (current == null) return false
}
// 2.根据对应的情况删除节点
// 2.1删除的节点是叶子节点(没有子节点)
if (current.left == null && current.right == null) {
if (current == this.root) {
this.root = null
} else if (isLeftChild) {
parent.left = null
} else {
parent.right = null
}
} else if (current.right == null) { // 2.2删除的节点有一个子节点
if (current == this.root) {
this.root = current.left
} else if (isLeftChild) {
parent.left = current.left
} else {
parent.right = current.left
}
} else if (current.left == null) {
if (current == this.root) {
this.root = current.right
} else if (isLeftChild) {
parent.left = current.right
} else {
parent.right = current.right
}
} else { // 2.3删除的节点有两个子节点
// 1.获取后继节点
var successor = this.getSuccssor(current)
// 2.判断是否根节点
if (current == this.root) {
this.root = successor
} else if (isLeftChild) {
parent.left = successor
} else {
parent.right = successor
}
// 3.将删除节点的左子树 = current.left
successor.left = current.left
}
}
// 找后继的方法
BinarySerachTree.prototype.getSuccssor = function (delNode) {
// 1.定义变量,保存找到的后继
var successor = delNode
var current = delNode.right
var successorParent = delNode
// 2.循环查找
while (current != null) {
successorParent = successor
successor = current
current = current.left
}
// 3.判断寻找的后继节点是否直接就是delNode的right节点
if (successor != delNode.right) {
successorParent.left = successor.right
successor.right = delNode.right
}
return successor
}
}
// 测试
// 1.创建BinarySerachTree
var bst = new BinarySerachTree()
// 2.插入数据
bst.insert(11)
bst.insert(7)
bst.insert(15)
bst.insert(5)
bst.insert(3)
bst.insert(9)
bst.insert(6)
bst.insert(8)
bst.insert(10)
bst.insert(13)
bst.insert(12)
bst.insert(14)
bst.insert(20)
bst.insert(18)
bst.insert(25)
// 3.测试遍历
// 1.测试先序遍历
var result = ''
bst.preOrderTraversal(function (key) {
result += key + ' '
})
// alert(result)
// 2.测试中序遍历
result = ''
bst.midOrderTraversal(function (key) {
result += key + ' '
})
// alert(result)
// 3.测试后序遍历
result = ''
bst.postOrderTraversal(function (key) {
result += key + ' '
})
// alert(result)
// 4.测试最值
// alert(bst.max())
// alert(bst.min())
// 5.测试查询方法
// alert(bst.search(25))
// alert(bst.search(24))
// alert(bst.search(2))
// 6.测试删除方法
// bst.remove(11)
// bst.remove(7)
// bst.remove(15)
// result = ''
// bst.postOrderTraversal(function (key) {
// result += key + ' '
// })
// alert(result)
</script>
</body>
</html>
JavaScript 数据结构-二叉搜索树
最新推荐文章于 2024-09-01 10:19:12 发布