class Node {
constructor(key) {
this.key = key;// 节点值
this.left = null;// 左指针
this.right = null;// 右指针
}
}
// 二叉树
export default class BinaryTree {
constructor() {
this.root = null;// 根节点
}
insert(key) {// api--插入
const newNode = new Node(key);
if (this.root === null) {// 设置根节点
this.root = newNode;
}
method.insertNode(this.root, newNode);
}
// callback为访问节点时执行的操作 中序排序
inorderTraversal(callback) {// api--中序遍历
method.inorderTraversalNode(this.root, callback);
}
preOrderTraversal(callback) {// api--前序遍历
method.preOrderTraversalNode(this.root, callback);
}
postOrderTraversal(callback) {// api--后序遍历
method.postOrderTraversalNode(this.root, callback);
}
max() { // 查找最大
return method.maxNode(this.root);
}
min() {
return method.minNode(this.root);
}
search(key) {
return method.searchNode(this.root, key);
}
remove(key) {
this.root = method.removeNode(this.root, key);
}
}
// method
const method = {
insertNode(root, newNode) {
if (newNode.key < root.key) {// 进入左子树
if (root.left === null) {// 左子树为空
root.left = newNode;
} else {// 左子树已存在
method.insertNode(root.left, newNode);
}
} else if (newNode.key > root.key) {// 进入右子树
if (root.right === null) {// 右子树为空
root.right = newNode;
} else {// 右子树已存在
method.insertNode(root.right, newNode);
}
}
},
inorderTraversalNode(node, callback) {
if (node) {// 当前节点
method.inorderTraversalNode(node.left, callback);// 遍历左子树
callback(node);// 访问节点
method.inorderTraversalNode(node.right, callback);// 遍历右子树
}
},
preOrderTraversalNode(node, callback) {
if (node) {// 当前节点
callback(node);// 访问节点
method.preOrderTraversalNode(node.left, callback);// 遍历左子树
method.preOrderTraversalNode(node.right, callback);// 遍历右子树
}
},
postOrderTraversalNode(node, callback) {
if (node) {// 当前节点
method.postOrderTraversalNode(node.left, callback);// 遍历左子树
method.postOrderTraversalNode(node.right, callback);// 遍历右子树
callback(node);// 访问节点
}
},
// 根据排序二叉树的特点,右子树的值都大于父节点的值。只需要进入节点的右子树查找,当某个节点的右子树为空时,该节点就是最大值节点。
maxNode(node) {
if (node) {
while (node.right !== null) {// 右子树不为空时
node = node.right;
}
return node.key;
}
return null;
},
// 查找最小值。根据排序二叉树的特点,左子树的值都小于父节点的值。只需要进入节点的左子树查找,当某个节点的左子树为空时,该节点就是最小值节点。
minNode(node) {
if (node) {
while (node.left !== null) {// 左子树不为空时
node = node.left;
}
return node.key;
}
return null;
},
// 根据排序二叉树的特点,比较给定值与节点值,小于时进入节点左子树。大于时进入节点右子树。等于时返回真。层层对比,最后如果子树为空,则表示没有找到。
searchNode(node, key) {
if (node === null) {// 没有找到
return false;
}
if (key < node.key) {// 进入左子树
return method.searchNode(node.left, key);
} else if (key > node.key) {// 进入右子树
return method.searchNode(node.right, key);
} else {// 找到了
return true;
}
},
removeNode(node, key) {
if (node === null) {// 没有找到值对应的节点
return null;
}
if (key < node.key) {// 给定值小于当前节点值
node.left = method.removeNode(node.left, key);
return node;
} else if (key > node.key) {// 给定值大于当前节点值
node.right = method.removeNode(node.right, key);
return node;
} else {// 找到给定值对应的节点
if (node.left === null && node.right === null) {// 节点为叶子节点
node = null;
return node;
}
if (node.left === null) {// 节点存在右子树
node = node.right;
return node;
} else if (node.right === null) {// 节点存在左子树
node = node.left;
return node;
}
// 节点存在左右子树时,先去右子树里找到最小值,然后用最小值替换节点值,最后进入右子树删除最小值对应的节点。
const minKey = method.minNode(node.right);
node.key = minKey;
method.removeNode(node.right, minKey);
return node;
}
}
};
// /// 使用
// // // 实例化二叉树
// const binaryTree = new BinaryTree();
// // // key值
// const keys = [1,19, 8, 15, 24, 45, 12, 5];
// // // 生成排序二叉树
// keys.forEach(key => binaryTree.insert(key));
// // console.log(binaryTree)
// // 中序遍历
// binaryTree.inorderTraversal(node => console.log(node.key));
// // 前序遍历
// // binaryTree.preOrderTraversal(node => console.log(node.key));
// // 后序遍历
// // binaryTree.postOrderTraversal(node => console.log(node.key));
// // binaryTree.remove(8);
// console.log(binaryTree)
js二叉树
最新推荐文章于 2024-03-13 11:30:31 发布