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;

 

測試:node

  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 ]

     

測試結果無誤。es6

若有錯誤,請指正,感謝。數組

相關文章
相關標籤/搜索