前言
最近关注了下扫描线算法,有涉及二叉树的地方,故找了点资料,用js实现了部分功能。
关于二叉树
完整实现代码
(function (w) {
// 树总集
let rootTree;
const binaryTree = (array = []) => {
return new BinaryTree(array);
}
// 空树构造函数
const Tree = function () {
// this.value;
// this.leftTree;
// this.rightTree;
}
/**
*
* 二叉树构造函数
* @param {array} array
*/
const BinaryTree = function (array) {
init(array);
}
BinaryTree.prototype = {
// 树总集
get rootTree () {
return rootTree;
}
}
// 插值
BinaryTree.prototype.add = function (value) {
addValue(value);
}
// 查询
BinaryTree.prototype.has = function (value) {
return hasValue(value);
}
// 最小值
BinaryTree.prototype.min = function () {
return minTree().value;
}
// 最大值
BinaryTree.prototype.max = function () {
return maxTree().value;
}
// 删除
BinaryTree.prototype.delete = function (value) {
return deleteValue(value);
}
// 清空
BinaryTree.prototype.clear = function () {
rootTree = new Tree();
}
// 前序
BinaryTree.prototype.preorderTraversal = function () {
return preorderTraversalRecursion();
}
// 中序
BinaryTree.prototype.inorderTraversal = function () {
return inorderTraversalRecursion();
}
// 后序
BinaryTree.prototype.postorderTraversal = function () {
return postorderTraversalRecursion();
}
const init = (array = []) => {
rootTree = new Tree();
array.forEach(v => addValue(v));
}
const addValue = (v, tree = rootTree) => {
if (tree.value === undefined) {
tree.value = v;
} else if (v < tree.value) {
if (tree.leftTree === undefined) {
tree.leftTree = new Tree();
}
addValue(v, tree.leftTree);
} else if (v > tree.value) {
if (tree.rightTree === undefined) {
tree.rightTree = new Tree();
}
addValue(v, tree.rightTree);
}
}
const hasValue = (v, tree = rootTree) => {
if (v === tree.value) return true;
if (v < tree.value && tree.leftTree) return hasValue(v, tree.leftTree);
else if (v > tree.value && tree.rightTree) return hasValue(v, tree.rightTree);
return false;
}
const minTree = (tree = rootTree) => {
if (tree.leftTree) {
return minTree(tree.leftTree);
}
return tree;
}
const maxTree = (tree = rootTree) => {
if (tree.rightTree) {
return maxTree(tree.rightTree);
}
return tree;
}
const deleteValue = (v, tree = rootTree) => {
if (v === tree.value) return promotionTree(tree);
else if (v < tree.value && tree.leftTree) return deleteValue(v, tree.leftTree);
else if (v > tree.value && tree.rightTree) return deleteValue(v, tree.rightTree);
// 没有匹配到
return false;
}
const promotionTree = tree => {
let tempTree;
if (tree.rightTree) {
tempTree = minTree(tree.rightTree);
} else if (tree.leftTree) {
tempTree = minTree(tree.leftTree);
} else {
delete tree.value;
return true;
}
tree.value = tempTree.value;
return promotionTree(tempTree);
}
// 前序遍历
const preorderTraversalRecursion = (tree = rootTree, result = []) => {
if (tree.value !== undefined) result.push(tree.value);
if (tree.leftTree) preorderTraversalRecursion(tree.leftTree, result);
if (tree.rightTree) preorderTraversalRecursion(tree.rightTree, result);
return result;
}
// 中序遍历
const inorderTraversalRecursion = (tree = rootTree, result = []) => {
if (tree.leftTree) inorderTraversalRecursion(tree.leftTree, result);
if (tree.value !== undefined) result.push(tree.value);
if (tree.rightTree) inorderTraversalRecursion(tree.rightTree, result);
return result
}
// 后序遍历
const postorderTraversalRecursion = (tree = rootTree, result = []) => {
if (tree.leftTree) postorderTraversalRecursion(tree.leftTree, result);
if (tree.rightTree) postorderTraversalRecursion(tree.rightTree, result);
if (tree.value !== undefined) result.push(tree.value);
return result
}
w.bt = w.binarytree = binaryTree;
})(window);
代码使用说明
创建二叉树
const arr = [8,55,0,12,1,2,33];
// 实例化
const bt = binarytree(arr);
// 打印二叉树总集
console.log(bt.rootTree)
// 结果
{
value: 8,
leftTree: {
value: 0,
rightTree: {
value: 1,
rightTree: {
value: 2,
},
},
},
rightTree: {
value: 55,
leftTree: {
value: 12,
rightTree: {
value: 33,
},
},
}
}
插值
const temp = [222,566,-12];
// 实例化
const bt = binarytree(arr);
// 插值
temp.forEach(v => bt.add(v));
// 打印二叉树总集
console.log(bt.rootTree)
// 结果
{
value: 8,
leftTree: {
value: 0,
leftTree: {
value: -12,
},
rightTree: {
value: 1,
rightTree: {
value: 2,
},
},
},
rightTree: {
value: 55,
leftTree: {
value: 12,
rightTree: {
value: 33,
},
},
rightTree: {
value: 222,
rightTree: {
value: 566,
},
},
}
}
删除操作
// 删除
bt.delete(0)
bt.delete(8)
// 打印二叉树总集
console.log(bt.rootTree)
// 结果
{
value: 12,
leftTree: {
value: 1,
leftTree: {
value: -12,
},
rightTree: {
value: 2,
},
},
rightTree: {
value: 55,
leftTree: {
value: 33,
},
rightTree: {
value: 222,
rightTree: {
value: 566,
},
},
}
}
查询、最大、最小
bt.has(33); // true
bt.has(0) // false
bt.min() // -12
bt.max() // 556
前序、中序、后序
// 前序
console.log(bt.preorderTraversal());
// 结果 [12, 1, -12, 2, 55, 33, 222, 566]
// 中序
console.log(bt.inorderTraversal());
// 结果 [-12, 1, 2, 12, 33, 55, 222, 566]
// 中序
console.log(bt.postorderTraversal());
// 结果 [-12, 2, 1, 33, 566, 222, 55, 12]
清空
bt.clear();
// 打印二叉树总集
console.log(bt.rootTree)
// 结果为空树 {}