"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
let tree = new BinaryTree(); let a = [123,45,456,-89,68,5,235,-78];
a.forEach(item => {
tree.insert(item);
});
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 } }
tree.traversal('pre'); console.log(tree.result_array); // [ 123, -89, -78, 5, 45, 68, 235, 456 ]
tree.traversal('in'); console.log(tree.result_array); // [ -89, -78, 5, 45, 68, 123, 235, 456 ]
tree.traversal('post'); console.log(tree.result_array); // [ -78, 5, -89, 68, 45, 235, 456, 123 ]
測試結果無誤。es6
若有錯誤,請指正,感謝。數組