雖然說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;
}
};
}
不過大概是因為它的設計彈性太高,大部分的程式語言似乎都沒有高完成度的容器實作
有時候要依自己需求調整還是只能自己刻一個
這個範例用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驗證純粹是我這次實作的主要目的,不見得在其他人的需求中
留言
張貼留言