js 实现二叉排序树

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树
(1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
 
代码实现:tree.js
代码是基于es6写的:
"use strict";

class BinaryTree {
    // 初始化树
    constructor () {
        this.root = null;
        this.result_array = [];
    }

    /**
     * @description 节点对象
     * @param {string/number}     order     节点的权值
     * @param {any}             value     节点的值
     * @return {object}                 节点对象
     */
    Node (order, value) {
        return {
            order: order,    //节点的权值
            value: value || order,    //节点的值
            left: null,    //左孩子节点
            right: null,    //右孩子节点
        }
    }

    /**
     * @description 递归插入节点
     * @param       {object(Node)}                 node     原节点
     * @param       {object(Node)}                 new_node 新插入的节点
     */
    insertNode(node, new_node) {
        // 新节点的权值小于原节点则递归插入左孩子
        if(new_node.order < node.order){
            if(!node.left){
                node.left = new_node;
            }else{
                this.insertNode(node.left, new_node);
            }
        // 新节点的权值不小于原节点则递归插入右孩子
        }else{
            if(!node.right){
                node.right = new_node;
            }else{
                this.insertNode(node.right, new_node);
            }
        }
    }

    /**
     * @description 执行插入节点(此方法供外部调用)
     * @param       {string/number}                 order 要插入节点的权值
     * @param       {object(Node)}                     node  要插入的节点
     */
    insert(order, node) {
        var new_node = this.Node(order, node);
        if(!this.root){
            this.root = new_node;
        }else{
            this.insertNode(this.root, new_node)
        }
    }

    /**
     * @description 递归先序遍历
     * @param       {object(Node)}           node     要递归的节点
     * @param       {Function}               callback 回调
     */
    preorderTraversalRecursion(node, callback) {
        if(node !== null){
            this.result_array.push(node.value);
            callback && callback(node);
            // 先遍历左孩子
            this.inorderTraversalRecursion(node.left, callback);
            // 再遍历父节点
            // 后遍历右孩子
            this.inorderTraversalRecursion(node.right, callback);
        }
    }

    /**
     * @description 递归中序遍历
     * @param       {object(Node)}           node     要递归的节点
     * @param       {Function}               callback 回调
     */
    inorderTraversalRecursion(node, callback) {
        if(node !== null){
            // 先遍历左孩子
            this.inorderTraversalRecursion(node.left, callback);
            // 再遍历父节点
            this.result_array.push(node.value);
            callback && callback(node);
            // 后遍历右孩子
            this.inorderTraversalRecursion(node.right, callback);
        }
    }

    /**
     * @description 递归后序遍历
     * @param       {object(Node)}           node     要递归的节点
     * @param       {Function}               callback 回调
     */
    postorderTraversalRecursion(node, callback) {
        if(node !== null){
            // 先遍历左孩子
            this.postorderTraversalRecursion(node.left, callback);
            // 再遍历右孩子
            this.postorderTraversalRecursion(node.right, callback);
            // 后遍历父节点
            this.result_array.push(node.value);
            callback && callback(node);
        }
    }

    /**
     * @description 执行遍历
     * @param       {enum(pre/in/post)}   type     回调
     * @return      {array}                      遍历后的数组
     */
    traversal(type) {
        this.result_array = [];
        this[`${type}orderTraversalRecursion`] && this[`${type}orderTraversalRecursion`](this.root);
        return this.result_array;
    }
}

module.exports.BinaryTree = BinaryTree;

 

测试:

  1. new 一个二叉树对象和一个乱序对象:
    let tree = new BinaryTree();
    let a = [123,45,456,-89,68,5,235,-78];
  2. 把乱序对象的元素插入到树中:
    a.forEach(item => {
      tree.insert(item);
    });
  3. 打印这个树:
    const util = require('util');
    console.log(util.inspect(tree.root, true, 100, true));
    // 结果如下
    { order:
    123, value: 123, left: { order: 45, value: 45, left: { order: -89, value: -89, left: null, right: { order: 5, value: 5, left: { order: -78, value: -78, left: null, right: null }, right: null } }, right: { order: 68, value: 68, left: null, right: null } }, right: { order: 456, value: 456, left: { order: 235, value: 235, left: null, right: null }, right: null } }
  4. 对二叉树进行先序遍历:
    tree.traversal('pre');
    console.log(tree.result_array);
    
    //    [ 123, -89, -78, 5, 45, 68, 235, 456 ]
  5. 对二叉树进行中序遍历(只有中序遍历是有序的):
    tree.traversal('in');
    console.log(tree.result_array);
    
    //    [ -89, -78, 5, 45, 68, 123, 235, 456 ]
  6. 对二叉树进行后序遍历:
    tree.traversal('post');
    console.log(tree.result_array);
    
    //    [ -78, 5, -89, 68, 45, 235, 456, 123 ]

     

测试结果无误。

如有错误,请指正,感谢。

posted @ 2017-12-13 19:20  参与商  阅读(912)  评论(5编辑  收藏  举报