// 初始化树的节点
class Node{
constructor(val) {
this.key = val; // 该节点的值
this.left = undefined; // 初始化左节点
this.right = undefined; // 初始化右节点
}
}
// 初始化树
class BirTree{
constructor(arr){
this.root = undefined; // 初始化根节点
arr.forEach((item) => { // 遍历数组每个节点并执行insert方法
this.insert(item);
})
}
insert(key) {
if(!this.root) { // 判断 如果根节点没有值则创建根节点
this.root = new Node(key);
}else{ // 如果有根节点则调用insetNode方法
this.insertNode(this.root,key);
}
}
insertNode(node,key) {
// 判断 该节点是否大于根节点的值
if(node.key < key){
// 如果大于根节点的值则判断根节点是否含有右节点
if(!node.right){
// 如果没有 创建右节点
node.right = new Node(key);
}else{
// 如果有 递归调用insertNode方法 继续比较判断根节点的右节点
this.insertNode(node.right,key);
}
}else{
// 如果小于根节点的值则判断根节点是否含有左节点
if(!node.left){
// 如果没有 创建左节点
node.left = new Node(key);
}else{
// 如果有 递归调用insertNode方法 继续比较判断根节点的左节点
this.insertNode(node.left,key);
}
}
}
min() {
// 输出该树的最小值
function fn(node) {
while(node.left) {
node = node.left;
}
return node.key;
}
return fn(this.root);
}
max() {
// 输出该树的最大值
function fn(node) {
while(node.right) {
node = node.right;
}
return node.key;
}
return fn(this.root);
}
middle() {
// 中序遍历
// 先遍历左子树,然后根结点,再右子树
function fn(node) {
if(node.left) {
fn(node.left);
}
console.log(node.key);
if(node.right) {
fn(node.right);
}
}
fn(this.root);
}
front() {
// 前序遍历
// 先遍历根结点,然后左子树,再右子树
function fn(node) {
console.log(node.key);
if(node.left) {
fn(node.left);
}
if(node.right) {
fn(node.right);
}
}
fn(this.root);
}
rear() {
// 后序遍历
// 先遍历左子树,然后右子树,再根结点
function fn(node) {
if(node.left) {
fn(node.left);
}
if(node.right) {
fn(node.right);
}
console.log(node.key);
}
fn(this.root);
}
}
let bt = new BirTree([6,3,5,4,8,7]);
console.log(bt);
console.log(bt.min());
console.log(bt.max());
console.log(bt.middle());
说一下大体思路,首先判断并创建根节点,然后遍历数组每个元素,先和根节点作比较,如果小于根节点则放在根节点的左子树中,如果大于根节点则放在根节点的右子树中,然后再判断根节点的左(右)节点有没有值,如果没有则直接利用该元素的值创建节点,如果有则递归调用insertNode方法和下一节点作比较,直至该元素找到合适的位置创建节点。