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

    const Comepare = {
        LESS_THAN: -1,
        BIGGER_THAN: 1,
        EQUALS: 0
    }
    function defaultCompare(a, b) {
        if (a === b) {
            return Comepare.EQUALS;
        }
        return a < b ? Comepare.LESS_THAN : Comepare.BIGGER_THAN;
    
    }
    class Node {
        constructor(key) {
            this.key = key;
            this.left = null;
            this.right = null;
        }
        toString() {
            return `${this.key}`;  //相当于强制转化成字符串
        }
    }
    
    class BinarySearchTree {
        constructor(comepareFn = defaultCompare) {
            this.comepareFn = comepareFn;
            this.root = undefined;
        }
        insert(key) {
            if (this.root == null) {
                this.root = new Node(key);
            } else {
                insertNode(this.root, key);
            }
        }
        insertNode(fatherNode, key) {
            if (this.comepareFn(key, fatherNode.key) === Comepare.LESS_THAN) {
                if (fatherNode.left != null) {
                    this.insertNode(fatherNode.left, key);
                } else {
                    fatherNode.left = new Node(key);
                }
            } else {
                if (fatherNode.right != null) {
                    this.insertNode(fatherNode.right, key);
                } else {
                    fatherNode.right = new Node(key);
                }
            }
    
        }
        inOrderTraverse(callback) {  //中序遍历
            this.inOrderTraverseNode(this.root, callback);
        }
        inOrderTraverseNode(fatherNode, callback) {  //遍历这个节点
            if (fatherNode != null) {
                this.inOrderTraverseNode(fatherNode.left, callback);
                callback(fatherNode.key);
                this.inOrderTraverseNode(fatherNode.right, callback);
            }
        }
        preOrderTraverse(callback) {  //树的遍历,相当于遍历以根节点为结点的子树
            this.preOrderTraverseNode(this.root, callback);
        }
        preOrderTraverseNode(fatherNode, callback) {   //先序的顺序遍历这个节点
            if (fatherNode != null) {
                callback(fatherNode.key);   //callback是回调函数,对这个数进行的操作
                preOrderTraverseNode(fatherNode.left, callback);
                preOrderTraverseNode(fatherNode.right, callback);
            }
        }
        postOrderTraverse(callback) {
            this.postOrderTraverseNode(this.root, callback);
        }
        postOrderTraverseNode(fatherNode, callback) {
            if (fatherNode != null) {
                postOrderTraverseNode(fatherNode.left, callback);
                postOrderTraverseNode(fatherNode.right, callback);
                callback(fatherNode.key);
            }
        }
        min() {
            return this.minNode(this.root);  //根节点下最小的值
        }
        mixNode(fatherNode) {             //找出从一个结点下子树的最小值
            if (fatherNode == null) {     //如果这个结点为空返回null
                return null;
            }
            current = fatherNode;
            while (current.next != null) {   //左节点有位置current就向做推一个
                current = current.next;
            }
            return current;
        }
        max() {
            return this.maxNode(this.root);
        }
        maxNode(fatherNode) {
            if (fatherNode == null) {
                return null;
            }
            let current = fatherNode;
            while (current.next != null) {
                current = current.next;
            }
            return current;
        }
        search(key) {
            return this.searchNode(this.root, key);
        }
        searchNode(fatherNode, key) {   //从fatherNode作为根节点的子树查找key
            if (fatherNode == null) {   //树为空树
                return false;
            }
            if (this.comepareFn(key, fatherNode.key) === Comepare.LESS_THAN) {
                return this.searchNode(fatherNode.left, key);  //小于当前点上的key
            } else if (this.comepareFn(key, fatherNode.key) === Comepare.BIGGER_THAN) {
                return this.searchNode(fatherNode.right, key);  //大于当前点的key
            } else {  //等于当前节点的key
                return true;  
            }
    
        }
        remove(key) {
            this.root= this.removeNode(this.root, key);
        }
        removeNode(fatherNode, key) {
            if (fatherNode == null) {   //如果结点为空结束
                return null;
            }
            if (this.comepareFn(key, fatherNode.key) === LESS_THAN) {
                fatherNode.left= this.removeNode(fatherNode.left, key);
                return fatherNode;
            } else if (this.comepareFn(key, fatherNode.key) === BIGGER_THAN) {
                fatherNode.right = this.removeNode(fatherNode.right, key);
                return fatherNode;
            } else {           //键值等于结点的键值
                if (fatherNode == null && fatherNode == null) {  //当前节点是叶子节点
                    fatherNode = null; 
                    return fatherNode;
                } else if (fatherNode.left == null) {   //当前节点有一个孩子
                    fatherNode = fatherNode.right;
                    return fatherNode;
                } else if (fatherNode.right == null) {  //当前节点有一个有孩子
                    fatherNode = fatherNode.left;
                    return fatherNode;
                } else {    //当前节点有两个孩子
                    const rightMin = this.minNode(fatherNode.right);  //找到右子树的最小节点 
                    fatherNode.key = rightMin.key;   //放到当前节点
                    fatherNode.right = this.removeNode(fatherNode.right, rightMin.key);  //删除当前节点的最小结点
                    return fatherNode;
                }
            }
        }
    
    }
  • 相关阅读:
    为IIS启用ASP.NET 2.0
    使用css技术代替传统的frame技术
    So you want to replay an IIS web server log?
    令人疑惑的defaultValueAttribute
    关于 Web 测试中的 JavaScript 和 ActiveX 控件 【转载】
    如何控制浏览器打印效果
    Google Chart Api
    VSTS负载测试——如何:使用 SQL 创建结果存储区
    在windows service的代码中得到当前的目录
    CAN I WRITE AN ISAPI FILTER USING MANAGED CODE?
  • 原文地址:https://www.cnblogs.com/WP-WangPin/p/13949960.html
Copyright © 2011-2022 走看看