跳到主要內容

Tree Structure 實作

雖然說Tree也還算是常用到的結構
不過大概是因為它的設計彈性太高,大部分的程式語言似乎都沒有高完成度的容器實作
有時候要依自己需求調整還是只能自己刻一個
這個範例用JavaScript刻一個自用版,應該還有地方可以改進就是...
當然如果不考慮就瀏覽器的相容性,也許用 document.implementation.createDocument 可以少一些工
另外JSON等結構也可以模仿一部份的操作
總而言之就是如果不是真的確定非這個結構不行,是不必要自己刻輪子來用
Java等程式語言用的版本也可以參考這個的概念來改
GitHub檔案目錄

function TreeStruct() {
    function node(id) {
        this._id = id;
        this.previous = [];
        this.next = [];
    }

    this.dataTop = new node('');
    this.findNode = function (id, node) {
        node = node || this.dataTop;
        if (node._id === id) return node;
        else {
            for (var i = node.next.length; i--;) {
                var result = this.findNode(id, node.next[i]);
                if (result) return result;
            }
        }
    };
    this.setNode = function (id, children, checkCircularRecursion) {
        if (children && children.length) {
            var _self = this.findNode(id);
            if (!_self) {
                _self = new node(id);
                _self.previous.push(this.dataTop);
                this.dataTop.next.push(_self);
            }
            for (var j = children.length; j--;) {
                var child = this.findNode(children[j]);
                if (!child) {
                    child = new node(children[j]);
                }
                if (child.previous.indexOf(this.dataTop) !== -1) {
                    child.previous.pop();
                    this.dataTop.next.splice(this.dataTop.next.indexOf(child), 1);
                }
                child.previous.push(_self);
                if (checkCircularRecursion) {
                    if (!this.checkCircularRecursion(child) && _self !== child) {
                        if (_self.next.indexOf(child) === -1) _self.next.push(child);
                    } else {
                        child.previous.pop();
                        return false;
                    }
                } else {
                    _self.next.push(child);
                }
            }
        } else this.deleteNode(id);

        return true;
    };
    this.deleteNode = function (id) {
        var _self = this.findNode(id);
        var _n = _self.next,
            _p = _self.previous,
            i;
        for (i = _n.length; i--;) {
            _n[i].previous.splice(_n[i].previous.indexOf(_self), 1);
            if (_n[i].previous.length === 0) _n[i].previous.push(this.dataTop);
        }
        for (i = _p.length; i--;) {
            _p[i].next.splice(_p[i].next.indexOf(_self), 1);
        }
    };
    this.checkCircularRecursion = function (checkNode, currentNode) {
        if (checkNode === currentNode) return true;
        else {
            if (!currentNode) currentNode = checkNode;
            for (var k = currentNode.previous.length; k--;) {
                var result = this.checkCircularRecursion(checkNode, currentNode.previous[k]);
                if (result) return result;
            }
            return false;
        }
    };
}

資料的recursive驗證純粹是我這次實作的主要目的,不見得在其他人的需求中

留言