Javascript二叉搜索树实现

基本知识

二叉树:二叉树的所有结点的最大度数为2;
二叉搜索树:又称为二叉排序树,根节点与其左右子结点的满足以下关系:左子结点<根结点<右子结点;
完全二叉树:除最后一层外,其它各层达到该层最大结点数;结点为n的完全二叉树深度为log2(n+1);
第i层的最大结点数:2^(i-1);
深度为h的最大最大总节点数:2^h-1;

function BinarySearchTree() {
    /**
     * 二叉搜索树的初始化
     */
    var root = null;
    var Node = function (value) {
        this.value = value;
        this.left = null;
        this.right = null;
    }
    // var Node = (value) => {
    //   this.value = value;
    //   this.left = null;
    //   this.right = null;
    // }

    /**
     * 插入键值到binarySearchTree
     */
    this.insert = function (value) {
        var newNode = new Node(value);
        if (root === null) {
            root = newNode;
        } else {
            insertNode(root, newNode);
        }
    }
    /**
     * 插入子结点
     * @param {Node} node 
     * @param {Node} newNode 
     */
    var insertNode = function (node, newNode) {
        if (node.value > newNode.value) {
            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);
            }
        }
    }
    /**
     * 移除结点
     */
    this.remove = function (value) {
        root = removeNode(root, value);
    }
    /**
     * 递归寻找并移除结点
     * @param {Node} node 
     * @param {Node.value} value 需要移除的结点的值 
     */
    var removeNode = function (node, value) {
        if (node === null) {
            return null;
        }
        if (value < node.value) {
            node.left = removeNode(node.left, value);
        } else if (value > node.value) {
            node.right = removeNode(node.right, value);
        } else {
            //该结点为叶子结点
            if (node.left === null && node.rigth === null) {
                node = null;
            }
            //该结点有一个子结点
            else if (node.left === null) {
                node = node.right;
                //  node.right = null;
            } else if (node.right === null) {
                node = node.left;
                //  node.left = null;
            }
            //该结点有两个子结点,此时可以取左子树中的最大值代替根结点;当然也可以取右子树中的最小值代替根结点
            else if (node.left != null && node.right != null) {
                var temp = minRightNode(node.right);
                node.value = temp.value;
                node.right = removeNode(node.right, temp.value);
            }
        }
        return node;
    }
    var minRightNode = function (node) {
        if (node) {
            while (node && node.left != null) {
                node = node.left;
            }
            return node;
        }
        return null;
    }

    /**
     * 先序遍历binarySearchTree
     * @param {Function} callback 
     */
    this.preOrderTraverse = function (callback) {
        console.log("先序遍历:");
        preOrderTraverseNode(root, callback);
    }
    /**
     * 递归实现先序遍历
     * @param {Node} node 
     * @param {Fucntion} callback 
     */
    var preOrderTraverseNode = function (node, callback) {
        if (node != null) {
            callback(node);
            preOrderTraverseNode(node.left, callback);
            preOrderTraverseNode(node.right, callback);
        }
    }
	/** 
	* 非递归先序遍历
	*/
   this.preOrderTraverse2 = function (callback) {
        console.log('非递归先序遍历:');
        if (root) {
            let stack = [];
            stack.push(root);
            while (stack.length > 0) {
                pivot = stack.pop();
                console.log('pre: ', pivot.value);
                if (pivot.right) {
                    stack.push(pivot.right);
                }
                if (pivot.left) {
                    stack.push(pivot.left);
                }
            }
        }        
    }     


    /**
     * 中序遍历binarySearchTree
     * @param {Function} callback 
     */
    this.inOrderTraverse = function (callback) {
        console.log("中序遍历:");
        inOrderTraverseNode(root, callback);
    }
    /**
     * 递归实现中序遍历
     * @param {Node} node 
     * @param {Function} callback 
     */
    var inOrderTraverseNode = function (node, callback) {
        if (node != null) {
            inOrderTraverseNode(node.left, callback);
            callback(node);
            inOrderTraverseNode(node.right, callback);
        }
    }
    /**
    * 非递归中序遍历
    * /
    this.inOrderTraverse2 = function (callback) {
        console.log('非递归中序遍历:');
        if (root) {
            let stack = [];
            while (stack.length > 0 || root) {
                if (root) {
                    stack.push(root);
                    root = root.left;
                } else {
                    root = stack.pop();
                    callback(root)
                    root = root.right;
                }
            }
        }
    }
    
    /**
     * 后序遍历binarySearchTree
     * @param {Fucntion} callback 
     */
    this.postOrderTraverse = function (callback) {
        console.log("后序遍历:");
        postOrderTraverseNode(root, callback);
    }
    /**
     * 递归后续遍历
     * @param {Node} node 
     * @param {Function} callback 
     */
    var postOrderTraverseNode = function (node, callback) {
        if (node != null) {
            postOrderTraverseNode(node.left, callback);
            postOrderTraverseNode(node.right, callback);
            callback(node);
        }
    }
	/**
	* 非递归后序遍历
	* /
    this.postOrderTraverse2 = function (callback) {
        console.log('非递归后序遍历:');
        if (root) {
            let stack1 = [];
            let stack2 = [];
            stack1.push(root);
            while (stack1.length > 0) {
                pivot = stack1.pop();
                stack2.push(pivot);
                if (pivot.left) {
                    stack1.push(pivot.left);
                }
                if (pivot.right) {
                    stack1.push(pivot.right);
                }
            }
            while (stack2.length > 0) {
                callback(stack2.pop())
            }
        }
    }

    /**
     * 广度优先遍历
     */
    this.breadthTraverse = function (callback) {
        console.log('广度优先遍历:');
        breadthTraverseNode(root, callback);
    }

    var breadthTraverseNode = function (node, callback) {
        let stack = [];
        if (node) {
            stack.push(node);
        }
        while(stack.length > 0) {
            let cur = stack.shift();
            callback(cur);
            if (cur.left) stack.push(cur.left);
            if (cur.right) stack.push(cur.right);
        }
    }
    /**
     * 搜索结点
     */
    var isFind = false;
    this.search = function (value) {
        isFind = false;
        console.log(`搜索结点${value}`);
        searchNode(root, value);
        return isFind;
    };
    /**
     * 递归搜索结点
     * @param {Node} node 
     * @param {Node.value} value 
     */
    var searchNode = function (node, value) {
        if (node != null) {
            if (isFind) return;
            if (node.value > value) {
                searchNode(node.left, value);
            } else if (node.value < value) {
                searchNode(node.right, value);
            } else {
                isFind = true;
            }
        } else {
            isFind = false;
        }
    };
    /**
     * 搜索binarySearchTree中的最小值
     */
    this.min = () => {
        console.log("搜索最小值");
        return minNode(root);
    }
    var minNode = (node) => {
        if (node) {
            while (node && node.left != null) {
                node = node.left;
            }
            return node.value;
        }
        return null;
    }
    /**
  * 搜索binarySearchTree中最大值
  */
    this.max = function () {
        console.log("搜索最大值");
        return maxNode(root);
    }
    var maxNode = (node) => {
        if (node != null) {
            while (node && node.right) {
                node = node.right;
            }
            return node.value;
        }
        return null;
    }
        /** 
     * 查询树的深度
     */
    this.depth = function () {
        return maxDepth(root);
    }
    var maxDepth = function (node) {
        if (!node) return 0;
        return max(maxDepth(node.left), maxDepth(node.right)) + 1;
    }
}


/**
* 打印结点值
* @param {Node} node 
*/
var printNode = function (node) {
    console.log(node.value);
}

var tree = new BinarySearchTree();
tree.insert(7)
tree.insert(4)
tree.insert(1)
tree.insert(3)
tree.insert(11)
tree.insert(6)
tree.insert(8)
tree.insert(9)
tree.insert(13)
tree.preOrderTraverse(printNode);
tree.inOrderTraverse(printNode);
tree.postOrderTraverse(printNode);
tree.breadthTraverse(printNode);
console.log(tree.min());
console.log(tree.max());
console.log("================");
console.log(tree.search(11));

tree.remove(11);
tree.preOrderTraverse(printNode);
tree.inOrderTraverse(printNode);
tree.postOrderTraverse(printNode);
console.log(tree.min());
console.log(tree.max());
console.log("================");
console.log(tree.search(11));

结果:

先序遍历:
7
4
1
3
6
11
8
9
13
中序遍历:
1
3
4
6
7
8
9
11
13
后序遍历:
3
1
6
4
9
8
13
11
7
广度优先遍历:
7
4
11
1
6
8
13
3
9
搜索最小值
1
搜索最大值
13
================
搜索节点11
true
4
1
3
6
13
8
9
中序遍历:
1
3
4
6
7
8
9
13
后序遍历:
3
1
6
4
9
8
13
7
搜索最小值
1
搜索最大值
13
================
搜索节点11
false
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Neil-

你们的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值