1

起因

最近在看《数据结构与算法--javascript描述》,然后上npmjs.org去搜索,想找合适的库参考并记录下来,以备以后用时能拿来即用,最没有发现很合自己意的,于是就决定自己一一实现出来。

npmjs相关库

  • bin-search-tree 该作者同时写有其它几种树;

  • binary-search-tree 自带平衡功能。

编程思路

  • 参考了本人前面用C++写的版本,但原版本使用了父指针,本版本去掉了父指针;

  • 没有用递归,用迭代处理所有的细节;

  • 仔细处理了边界值,这是bug经常出没之地;

  • 删除左右孩子都不空的节点时,转右,然后向左到尽头(找待删结点的后继),以其后继取代被删结点的位置,然后删除其后继;

  • 以模块模式组织代码;

自己的实现

BSTNode.js

(function(){
    "use strict";

    function Node(data, left, right){
        this.data = data;
        this.left = left;
        this.right = right;
    }

    module.exports = Node;
})();

BSTree.js

(function(){
    "use strict";
    var Node = require("./lib/BSTNode");

    function BSTree(){
        this.root = null;
    }

    BSTree.prototype.remove = function(data){
        if(this.root == null)
            return false;
        var currNode = this.root;
        var parent = null;
        //注意边界值,如果被删除的是根结点,循环是不进入的,parent为null
        while(currNode != null && currNode.data != data) {
            parent = currNode;
            if(data < currNode.data){
                currNode = currNode.left;
            }else{
                currNode = currNode.right;
            }
        }
        if(currNode == null){
            return false;
        }
        if(currNode.left == null || currNode.right == null){  //至少有一个孩子为空时
            if(parent == null){                 //处理边界值,但左右子树同时存在时,不会出问题
                this.root = currNode.left == null ? currNode.right : currNode.left;
            }
            else if(parent.left == currNode){
                parent.left = currNode.left == null ? currNode.right : currNode.left;
            }
            else{
                parent.right = currNode.left == null ? currNode.right : currNode.left;
            }
        }else{    //孩子都不为空,找直接后继
            var mid = currNode.right;
            parent = currNode;
            while(mid.left != null){
                parent = mid;
                mid = mid.left;
            }
            currNode.data = mid.data;    //后继取代被删节点
            if(parent.left == mid){      //删除其后继
                parent.left = mid.right;
            }
            else{
                parent.right = mid.right;
            }
        }
        return true;
    };

    BSTree.prototype.find = function(data){
        var currNode = this.root;
        while(currNode != null){
            if(currNode.data == data){
                return currNode;
            }
            else if(data < currNode.data){
                currNode = currNode.left;
            }
            else{
                currNode = currNode.right;
            }
        }
        return null;
    };
    //取最小值
    BSTree.prototype.getMin = function(){
        var currNode = this.root;
        while(currNode.left != null){
            currNode = currNode.left;
        }
        return currNode.data;
    };
    //取最大值
    BSTree.prototype.getMax = function(){
        var currNode = this.root;
        while(currNode.right != null){
            currNode = currNode.right;
        }
        return currNode.data;
    };
    //后序遍历
    BSTree.prototype.postOrder = function(node){
        if(node != null){
            this.postOrder(node.left);
            this.postOrder(node.right);
            console.log(node.data);
        }
    };
    //前序遍历
    BSTree.prototype.preOrder = function(node){
        if(node != null){
            console.log(node.data);
            this.preOrder(node.left);
            this.preOrder(node.right);
        }
    };
    //中序遍历
    BSTree.prototype.inOrder = function(node){
        if(node != null){
            this.inOrder(node.left);
            console.log(node.data);
            this.inOrder(node.right);
        }
    };

    BSTree.prototype.insert = function(data){
        var node = new Node(data, null, null);
        if(this.root == null){
            this.root = node;
        }
        else{
            var currNode = this.root;
            var parent;    //因为没有父指针,需要存储当前节点的父节点
            while(true){
                parent = currNode;
                if(data < currNode.data){
                    currNode = currNode.left;
                    if(currNode == null){
                        parent.left = node;
                        break;
                    }
                }
                else{
                    currNode = currNode.right;
                    if(currNode == null){
                        parent.right = node;
                        break;
                    }
                }
            }
        }
    };

    module.exports = BSTree;
})();

源代码地址

https://github.com/zhoutk/js-data-struct
http://git.oschina.net/zhoutk/jsDataStructs

zhoutk
2.6k 声望1.2k 粉丝

自由程序员,技术路线c,delphi,c++,c#,java,php,node.js,python,golang,typescript;超喜欢react.js的设计思路,全栈开发成为我的终极目标。开发机器macbook pro,或装ubuntu、fedora的机器,编程用vim...