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;
    	}
    }
    
  • 相关阅读:
    位运算
    方法重载
    基本数据类型与引用数据类型参数
    带返回值方法的定义格式
    return使用
    方法的通用格式
    方法定义的格式
    google chrome developer tools
    Skolelinux
    ajax
  • 原文地址:https://www.cnblogs.com/cc-freiheit/p/10368078.html
Copyright © 2011-2022 走看看