zoukankan      html  css  js  c++  java
  • js 实现二叉树

    用 js 实现的二叉树数据结构,完成 先/中/后 序遍历、查找最 大/小 值、查找特定值以及删除节点(虽然没太理解)的操作。

    // 节点对象
    class Node {
        constructor(data) {
            this.root = this;
            this.data = data;
            this.left = null;
            this.right = null;
        }
    }
    
    // 二叉树
    class BST {
        constructor() {
            this.root = null;
        }
    
        // 插入节点
        insert(data) {
            let newNode = new Node(data);
            let insertNode = (node, newNode) => {
                if (newNode.data < node.data) {
                    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)
                    }
                }
            };
    
            if (!this.root) {
                this.root = newNode;
            } else {
                insertNode(this.root, newNode)
            }
        }
    
        /* 中序遍历 => 
            1.访问左子树(先访问左子树中的左子树,再访问左子树中的右子树); 
            2.访问根
            3.访问右子树(先访问右子树中的左子树,再访问右子树中的右子树)
    
            可以起到排序作用
        */
        inOrder() {
            let backs = [];
            let inOrderNode = (node, callback) => {
                if (node !== null) {
                    inOrderNode(node.left, callback);
                    backs.push(callback(node.data));
                    inOrderNode(node.right, callback);
                }
            }
    
            let callback = function(v) {
                return v
            }
            inOrderNode(this.root, callback);
            return backs
        }
    
        // 前序遍历 => 1.访问根节点; 2.访问左子树; 3.访问右子树
        preOrder() {
            let backs = [];
            let preOrderNode = (node, callback) => {
                if (node !== null) {
                    backs.push(callback(node.data));
                    preOrderNode(node.left, callback);
                    preOrderNode(node.right, callback);
                }
            }
            let callback = function(v) {
                return v
            }
            preOrderNode(this.root, callback);
            return backs
        }
    
        /* 后序遍历 =>
            1.访问左子树。(先访问左子树中的左子树,再访问左子树中的右子树)
            2.访问右子树。(先访问右子树中的左子树,再访问右子树中的右子树)
            3.访问根
        */
        postOrder(){
            let backs = [];
            const postOrderNode = (node,callback) => {
                if(node !== null){
                    postOrderNode(node.left,callback);
                    postOrderNode(node.right,callback);
                    backs.push(callback(node.data))
                }
            };
    
            let callback = function(v) {
                return v
            }
            postOrderNode(this.root,callback);
            return backs
        }
    
        // 查找最小值
        getMin(node) {
            let minNode = node => {
                return node ? (node.left ? minNode(node.left) : node) : null
            }
    
            return minNode(node || this.root)
        }
    
        // 查找最大值
        getMax(node) {
            let maxNode = node => {
                return node ? (node.right ? maxNode(node.right) : node) : null
            }
    
            return maxNode(node || this.root)
        }
    
        // 查找特定值
        find(data) {
            let findNode = (node, data) => {
                if (node == null) return false
                if (node.data === data) return node;
                return findNode((data < node.data) ? node.left : node.right, data);
            }
    
            return findNode(this.root, data);
        }
    
        // 删除节点
        // 返回新的二叉树?
        remove(data) {
            let removeNode = (node, data) => {
                if (node === null) return null;
                if (node.data === data) {
                    if (node.left === null && node.right === null) return null
                    if (node.left === null) return node.right;
                    if (node.right === null) return node.left;
                    if (node.left !== null && node.right !== null) {
                        let _node = this.getMin(node.right);
                        node.data = _node.data;
                        node.right = removeNode(node.right, data);
                        return node
                    }
                } else if (data < node.data) {
                    node.left = removeNode(node.left, data);
                    return node;
                } else {
                    node.right = removeNode(node.right, data);
                    return node;
                }
            }
    
            return removeNode(this.root, data)
        }
    }
    
    /***********************************/
    // some operation
    let datas = [11,7,5,3,6,9,8,10,20,14,12,25,18];
    let bst = new BST();
    datas.forEach(data => {
        bst.insert(data)
    })
    
    console.log(bst.getMax())
    console.log(bst.getMin())
    

    另一个实例:

    class BNode {
        constructor(val) {
            this.value = val;
            this.left = null;
            this.right = null;
        }
    }
    
    class BinaryTree {
        constructor() {
            this.root = null;
            this.values = new Array();
        }
    
        /**
         * insert 插入节点
         * @param {[ type ]} val [description]
         * @return {[ void ]}  [description]
         */
        insert(val) {
            this.values.push(val);
            let node = new BNode(val);
            if (!this.root) {
                this.root = node;
            } else {
                this._insertNode(this.root, node);
            }
        }
    
        /**
         * _insertNode 递归插入节点
         * @param  {[ BinaryNode ]} node    [父节点]
    	 * @param  {[ BinaryNode ]} newNode [新子节点]
         */
        _insertNode(node, newNode) {
            if (newNode.value < node.value) {
                if (node.left === null ){
                    node.left = newNode;
                } else {
                    this._insertNode(node.left, newNode);
                }
            } else {
                if (node.right === null) {
                    node.right = newNode;
                } else {
                    this._insertNode(node.right, newNode);
                }
            }
        }
    
        /**
    	 * [inOrderTraverse 中序遍历]
    	 * @return {[ Array ]} [description]
         */
        inOrderTraverse() {
            let result = new Array();
            this._inOrderTraverseNode(this.root, node => {
                result.push(node.value);
            })
            return result;
        }
    
        /**
    	 * [_inOrderTraverseNode 中序遍历递归]
    	 * @param  {[ BinaryNode ]}   node     [当前节点]
    	 * @param  { Function } callback [回调函数]
    	 * @return {[ void ]}            [description]
         */
        _inOrderTraverseNode(node, callback) {
            if (node) {
                this._inOrderTraverseNode(node.left, callback);
                callback(node);
                this._inOrderTraverseNode(node.right, callback);
            }
        }
    
        /**
    	 * [preOrderTraverse 先序遍历]
    	 * @return {[ Array ]} [description]
         */
        preOrderTraverse() {
            let result = new Array();
            this._preOrderTraverseNode(this.root, node => {
                result.push(node.value);
            })
            return result;
        }
    
        /**
    	 * [_preOrderTraverseNode 先序遍历递归]
    	 * @param  {[ BinaryNode ]}   node     [当前节点]
    	 * @param  { Function } callback [回调函数]
    	 * @return {[ Void ]}            [description]
         */
        _preOrderTraverseNode(node, callback) {
            if (node) {
                callback(node);
                this._preOrderTraverseNode(node.left, callback);
                this._preOrderTraverseNode(node.right, callback);
            }
        }
    
        /**
    	 * [postOrderTraverse 后序遍历]
    	 * @return {[Array]} [description]
         */
        postOrderTraverse() {
            let result = new Array();
            this._postOrderTraverseNode(this.root, node => {
                result.push(node.value);
            })
            return result;
        }
    
        /**
    	 * [_postOrderTraverseNode 后序遍历递归]
    	 * @param  {[BinaryNode]}   node     [当前节点]
    	 * @param  {Function} callback [回调函数]
    	 * @return {[type]}            [description]
         */
        _postOrderTraverseNode(node, callback) {
            if (node) {
                this._postOrderTraverseNode(node.left, callback);
                this._postOrderTraverseNode(node.right, callback);
                callback(node);
            }
        }
    
        /**
    	 * [remove 移除指定值]
    	 * @param  {[*]} val [目标值]
    	 * @return {[ Void ]}     [description]
         */
        remove(val) {
            this.root = this._removeNode(this.root, val);
        }
    
        /**
    	 * [_removeNode 移除节点递归]
    	 * @param  {[BinaryNode]} node [当前节点]
    	 * @param  {[*]} val  [要移的除节点值]
    	 * @return {[BinaryNode]}      [当前节点]
         */
        _removeNode(node, val) {
            if (node === null) return null;
            
            // 递归寻找目标节点
            if (val < node.value) {
                this._removeNode(node.left, val);
                return node;
            }
    
            if (val > node.value) {
                this._removeNode(node.right, val);
                return node;
            }
    
            // 找到目标节点
            if (val === node.value) {
                // 是叶子节点 (left
    ight没有节点)
                if (node.left === null && node.right === null) {
                    // 赋值 null, 表示删除
                    node = null;
                    return node;
                }
    
                // 只有一个子节点
                if (node.left === null) {
                    node = node.right;
                    return node;
                }
                if (node.right === null) {
                    node = node.left;
                    return node;
                }
    
                // 左右子节点都有
                let min_node = this._findMinNode(node);
                node.value = min_node.value;
                node.right = this._removeNode(node.right, min_node.value);
                return node;
            }
        }
    
        /**
    	 * [_findMinNode 查找最小节点]
    	 * @param  {[BinaryNode]} node [当前节点]
    	 * @return {[BinaryNode]}      [最小的节点]
         */
        _findMinNode(node) {
            while(node && node.left) {
                node = node.left;
            } 
            return node;
        }
    
        /**
    	 * [search 检索]
    	 * @param  {[ * ]} val [被检索值]
    	 * @return {[ Boolean ]}     [表示是否存在]
         */
        search(val) {
            let values = this.inOrderTraverse();
            return values.includes(val);
        }
    
        /**
    	 * [min 返回最小值]
    	 * @return {[ type ]} 最小值
         */
        min() {
            let values = this.inOrderTraverse();
            return values[0]
        }
    
        /**
    	 * [max 返回最小值]
    	 * @return {[ type ]} 最大值
         */
        max() {
            let values = this.inOrderTraverse();
            return values[values.length - 1]
        }
    
        /**
    	 * [isEmpty 是否为空二叉树]
    	 * @return {Boolean}
         */
    
        isEmpty() {
            return this.root === null;
        }
    
        /**
    	 * [breadthFirstSearch 广度优先遍历]
    	 * @return {[Array]} [遍历后结果]
    	 */
    	breadthFirstSearch() {
    		let result = new Array();
    		let content = new Array();
    		let current_node = null;
    		content.push(this.root);
    		while(content.length) {
    			current_node = content.shift();
    			result.push(current_node.value);
    			if (current_node.right) {
    				content.push(current_node.right);
    			}
    			if (current_node.left) {
    				content.push(current_node.left);
    			}
    		}
    		return result;
    	}
    }
    
  • 相关阅读:
    三个心态做人做学问 沧海
    成功走职场要找准自己的"快捷键" 沧海
    免费离线下载 拂晓风起
    Hibernate 获取某个表全部记录时 奇怪现象 (重复出现某个记录) 拂晓风起
    无法读取mdb 如果连接不了ACCESS mdb文件,就尝试安装MDAC 拂晓风起
    Netbeans 使用 Hibernate 逆向工程 生成hbm和pojo 拂晓风起
    如何点击单选框 radio 后面的文字,选中单选框 拂晓风起
    Java 连接access 使用access文件 不用配置 拂晓风起
    mysql下如何执行sql脚本 拂晓风起
    Hibernate配置access Hibernate 连接 access 拂晓风起
  • 原文地址:https://www.cnblogs.com/cc-freiheit/p/10368078.html
Copyright © 2011-2022 走看看