• 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 ]

    测试结果无误。

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

    飞鸟尽,良弓藏
  • 相关阅读:
    4.文本编辑器vi的简单实用与指针介绍
    3.理解make命令——编译源文件安装
    2.换一种方式理解linux命令行
    1.linux环境搭建
    Tomcat 何时解压war包
    正则表达式8---再谈小括号
    利用vue-resource模拟百度下拉列表
    那些年iframe的坑(一)
    $nextTick()的理解
    一个超简单的vue商品计算总金额
  • 原文地址:https://www.cnblogs.com/shenshangzz/p/8034508.html
Copyright © 2020-2023  润新知