用 js 实现的二叉树数据结构,完成 先/中/后 序遍历、查找最 大/小 值、查找特定值以及删除节点(虽然没太理解)的操作。
// 节点对象
class Node {
constructor(data) {
this.root = this;
this.data = data;
this.left = null;
this.right = null;
}
}
// 二叉树
class BST {
constructor() {
this.root = null;
}
// 插入节点
insert(data) {
let newNode = new Node(data);
let insertNode = (node, newNode) => {
if (newNode.data < node.data) {
if (node.left === null) {
node.left = newNode;
} else {
insertNode(node.left, newNode);
}
} else {
if (node.right === null) {
node.right = newNode;
} else {
insertNode(node.right, newNode)
}
}
};
if (!this.root) {
this.root = newNode;
} else {
insertNode(this.root, newNode)
}
}
/* 中序遍历 =>
1.访问左子树(先访问左子树中的左子树,再访问左子树中的右子树);
2.访问根
3.访问右子树(先访问右子树中的左子树,再访问右子树中的右子树)
可以起到排序作用
*/
inOrder() {
let backs = [];
let inOrderNode = (node, callback) => {
if (node !== null) {
inOrderNode(node.left, callback);
backs.push(callback(node.data));
inOrderNode(node.right, callback);
}
}
let callback = function(v) {
return v
}
inOrderNode(this.root, callback);
return backs
}
// 前序遍历 => 1.访问根节点; 2.访问左子树; 3.访问右子树
preOrder() {
let backs = [];
let preOrderNode = (node, callback) => {
if (node !== null) {
backs.push(callback(node.data));
preOrderNode(node.left, callback);
preOrderNode(node.right, callback);
}
}
let callback = function(v) {
return v
}
preOrderNode(this.root, callback);
return backs
}
/* 后序遍历 =>
1.访问左子树。(先访问左子树中的左子树,再访问左子树中的右子树)
2.访问右子树。(先访问右子树中的左子树,再访问右子树中的右子树)
3.访问根
*/
postOrder(){
let backs = [];
const postOrderNode = (node,callback) => {
if(node !== null){
postOrderNode(node.left,callback);
postOrderNode(node.right,callback);
backs.push(callback(node.data))
}
};
let callback = function(v) {
return v
}
postOrderNode(this.root,callback);
return backs
}
// 查找最小值
getMin(node) {
let minNode = node => {
return node ? (node.left ? minNode(node.left) : node) : null
}
return minNode(node || this.root)
}
// 查找最大值
getMax(node) {
let maxNode = node => {
return node ? (node.right ? maxNode(node.right) : node) : null
}
return maxNode(node || this.root)
}
// 查找特定值
find(data) {
let findNode = (node, data) => {
if (node == null) return false
if (node.data === data) return node;
return findNode((data < node.data) ? node.left : node.right, data);
}
return findNode(this.root, data);
}
// 删除节点
// 返回新的二叉树?
remove(data) {
let removeNode = (node, data) => {
if (node === null) return null;
if (node.data === data) {
if (node.left === null && node.right === null) return null
if (node.left === null) return node.right;
if (node.right === null) return node.left;
if (node.left !== null && node.right !== null) {
let _node = this.getMin(node.right);
node.data = _node.data;
node.right = removeNode(node.right, data);
return node
}
} else if (data < node.data) {
node.left = removeNode(node.left, data);
return node;
} else {
node.right = removeNode(node.right, data);
return node;
}
}
return removeNode(this.root, data)
}
}
/***********************************/
// some operation
let datas = [11,7,5,3,6,9,8,10,20,14,12,25,18];
let bst = new BST();
datas.forEach(data => {
bst.insert(data)
})
console.log(bst.getMax())
console.log(bst.getMin())
另一个实例:
class BNode {
constructor(val) {
this.value = val;
this.left = null;
this.right = null;
}
}
class BinaryTree {
constructor() {
this.root = null;
this.values = new Array();
}
/**
* insert 插入节点
* @param {[ type ]} val [description]
* @return {[ void ]} [description]
*/
insert(val) {
this.values.push(val);
let node = new BNode(val);
if (!this.root) {
this.root = node;
} else {
this._insertNode(this.root, node);
}
}
/**
* _insertNode 递归插入节点
* @param {[ BinaryNode ]} node [父节点]
* @param {[ BinaryNode ]} newNode [新子节点]
*/
_insertNode(node, newNode) {
if (newNode.value < node.value) {
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);
}
}
}
/**
* [inOrderTraverse 中序遍历]
* @return {[ Array ]} [description]
*/
inOrderTraverse() {
let result = new Array();
this._inOrderTraverseNode(this.root, node => {
result.push(node.value);
})
return result;
}
/**
* [_inOrderTraverseNode 中序遍历递归]
* @param {[ BinaryNode ]} node [当前节点]
* @param { Function } callback [回调函数]
* @return {[ void ]} [description]
*/
_inOrderTraverseNode(node, callback) {
if (node) {
this._inOrderTraverseNode(node.left, callback);
callback(node);
this._inOrderTraverseNode(node.right, callback);
}
}
/**
* [preOrderTraverse 先序遍历]
* @return {[ Array ]} [description]
*/
preOrderTraverse() {
let result = new Array();
this._preOrderTraverseNode(this.root, node => {
result.push(node.value);
})
return result;
}
/**
* [_preOrderTraverseNode 先序遍历递归]
* @param {[ BinaryNode ]} node [当前节点]
* @param { Function } callback [回调函数]
* @return {[ Void ]} [description]
*/
_preOrderTraverseNode(node, callback) {
if (node) {
callback(node);
this._preOrderTraverseNode(node.left, callback);
this._preOrderTraverseNode(node.right, callback);
}
}
/**
* [postOrderTraverse 后序遍历]
* @return {[Array]} [description]
*/
postOrderTraverse() {
let result = new Array();
this._postOrderTraverseNode(this.root, node => {
result.push(node.value);
})
return result;
}
/**
* [_postOrderTraverseNode 后序遍历递归]
* @param {[BinaryNode]} node [当前节点]
* @param {Function} callback [回调函数]
* @return {[type]} [description]
*/
_postOrderTraverseNode(node, callback) {
if (node) {
this._postOrderTraverseNode(node.left, callback);
this._postOrderTraverseNode(node.right, callback);
callback(node);
}
}
/**
* [remove 移除指定值]
* @param {[*]} val [目标值]
* @return {[ Void ]} [description]
*/
remove(val) {
this.root = this._removeNode(this.root, val);
}
/**
* [_removeNode 移除节点递归]
* @param {[BinaryNode]} node [当前节点]
* @param {[*]} val [要移的除节点值]
* @return {[BinaryNode]} [当前节点]
*/
_removeNode(node, val) {
if (node === null) return null;
// 递归寻找目标节点
if (val < node.value) {
this._removeNode(node.left, val);
return node;
}
if (val > node.value) {
this._removeNode(node.right, val);
return node;
}
// 找到目标节点
if (val === node.value) {
// 是叶子节点 (left
ight没有节点)
if (node.left === null && node.right === null) {
// 赋值 null, 表示删除
node = null;
return node;
}
// 只有一个子节点
if (node.left === null) {
node = node.right;
return node;
}
if (node.right === null) {
node = node.left;
return node;
}
// 左右子节点都有
let min_node = this._findMinNode(node);
node.value = min_node.value;
node.right = this._removeNode(node.right, min_node.value);
return node;
}
}
/**
* [_findMinNode 查找最小节点]
* @param {[BinaryNode]} node [当前节点]
* @return {[BinaryNode]} [最小的节点]
*/
_findMinNode(node) {
while(node && node.left) {
node = node.left;
}
return node;
}
/**
* [search 检索]
* @param {[ * ]} val [被检索值]
* @return {[ Boolean ]} [表示是否存在]
*/
search(val) {
let values = this.inOrderTraverse();
return values.includes(val);
}
/**
* [min 返回最小值]
* @return {[ type ]} 最小值
*/
min() {
let values = this.inOrderTraverse();
return values[0]
}
/**
* [max 返回最小值]
* @return {[ type ]} 最大值
*/
max() {
let values = this.inOrderTraverse();
return values[values.length - 1]
}
/**
* [isEmpty 是否为空二叉树]
* @return {Boolean}
*/
isEmpty() {
return this.root === null;
}
/**
* [breadthFirstSearch 广度优先遍历]
* @return {[Array]} [遍历后结果]
*/
breadthFirstSearch() {
let result = new Array();
let content = new Array();
let current_node = null;
content.push(this.root);
while(content.length) {
current_node = content.shift();
result.push(current_node.value);
if (current_node.right) {
content.push(current_node.right);
}
if (current_node.left) {
content.push(current_node.left);
}
}
return result;
}
}