几天前,应项目的要求开发了一个新的树控件.使用后,开发人员反应良好,效率有了质的提升. 其中一个核心算法如下:
_generate_tree: function(pnode, items) {
if (items.length === 0) return;
var item, node, id, text, pid, level, checked;
for (var i = items.length - 1; i >= 0; i--) {
item = items[i];
pid = item["parentid"];
if (pid === pnode.id) {
id = item["id"];
text = item["text"];
level = pnode["level"] + 1;
checked = item["checked"];
node = new Node(id, pnode, text, level, checked);
pnode.add(node);
this.nodes[id] = node;
this.dataset[id] = item;
items = items.slice(0);
items.splice(i, 1);
arguments.callee.call(this, node, items);
}
}
}
用于生成树的存储结构如下:
[{"id":"1","parentid":"0","text":"全网组织"},{"id":"58","parentid":"1","text":"asdfasdfdsa"},{"id":"2","parentid":"1","text":"商户组织"},{"id":"3","parentid":"1","text":"用户组织"},{"id":"4","parentid":"1","text":"运维部"},{"id":"64","parentid":"2","text":"nnnnn"},{"id":"65","parentid":"2","text":"vvvvv"},{"id":"63","parentid":"2","text":"mmmmm"},{"id":"55","parentid":"2","text":"vwfwefwef"},{"id":"61","parentid":"2","text":"tetetetetet"},{"id":"23","parentid":"2","text":"testtest"},{"id":"25","parentid":"2","text":"劳而无功"},{"id":"47","parentid":"2","text":"1313"},{"id":"46","parentid":"2","text":"12"},{"id":"48","parentid":"2","text":"14"},{"id":"43","parentid":"2","text":"5678"}]
备注:用于生成树的存储结构是无序的.node是树的一个节点,有相应的属性及方法.
这个构造树的函数可以很好的工作,思路也清晰明了.只是效率是 n! ,接近平方级.
一般现实使用中,用于生成树的数据都不会很多;很多的话,都是采用点击异步加载的方式来实现. 所以,测试人员也没有提出意见.
我在作代码审查的时候,作了一个性能测试.用2000多条记录生成一个树.
chrome下表现尚可, 稳定在160ms左右;在ie7,则达到了4s左右.OMG,这个简直无法令人接受.
深思熟虑后,提供了一个改进后的算法.
_generate_tree2: function(root, items) {
if (items.length === 0) return;
var self = this;
var item, node, id, text, pid,rid = root.id, level, checked,dict = {};
for (var i = items.length - 1; i >= 0; i--) {
item = items[i];
pid = item["parentid"];
if( !dict[pid] ){
dict[pid] = [];
}
dict[pid].push(item);
(function(pid,pnode) {
var cs = dict[pid];
if(!cs) return;
for (var j = 0; j < cs.length; j++) {
item = cs[j];
id = item["id"];
text = item["text"];
level = pnode["level"] + 1;
checked = item["checked"];
node = new Node(id, pnode, text, level, checked);
pnode.add(node);
self.nodes[id] = node;
self.dataset[id] = item;
arguments.callee.call(self, node.id, node);
})(rid,root);
}
这次测试后,在chrome下稳定在4ms左右,在ie7下则稳定在60ms左右.so perfect!
效率基本接近是线性了. 哈.. 还能再改进吗? 大拿们.
浙公网安备 33010602011771号