是的,
书上是这么说,
一准,不会错
但,我想说
要思考,思考特殊情况
是否存在
列表转树
在实际开发中,像多级菜单、省市区联动等在客户端的结构一般为树状结构。
[
{
id:1,
name:'北京',
parentId:0,
children:[
{
id:2,
name:'海淀区',
parentId:1,
children:[
{
id:3,
name:'上庄镇',
parentId:2
}
]
}
]
}
]
这类数据在服务端存储时却是下述这样的二维表,如果服务端人员很懒,没有进行转换,而是直接把数据原样扔了过来,那我们就只能自己进行转换了。
| id | name | parentId |
|---|---|---|
| 1 | 北京 | 0 |
| 2 | 海淀区 | 1 |
| 3 | 上庄镇 | 2 |
预处理模式的二次循环算法
首先,第一次遍历,以parentId为键,将所有parentId相同数据归类。
然后,第二次遍历,这时有内循环了。
但是,要注意到一点,这个内循环有个特点,就是其j<total,这个total是动态的,有可能是0,有可能是m,但是执行n次的话,其总执行次数永远为n。
Array.prototype.toTree = function(
config = {
key:'id',
pid:'parentId',
chidren:'chidren',
value:'0'
})
{
let tree = [];
let relation = {}; relation[config.value] = [];
let count = this.length;
//第一次遍历,N
for(let i = 0;i < count;i++)
{
let key =this[i][config.pid];
if(!relation[key])
{
relation[key] = [];
}
relation[key].push(i);
}
//第二次遍历,N
for(let i = 0;i < count;i++)
{
let key = this[i][config.key];
if(relation[key])
{
let total = relation[key].length;
this[i][config.chidren] = [];
for(let j = 0;j < total;j++)
{
this[i][config.chidren].push(this[relation[key][j]]);
}
}
}
relation[config.value].forEach(element => {
tree.push(this[element]);
});
return tree;
}
再看下面两个例子
写法1,内循环是个固定数字4
写法2,没有内循环
但是两个写法结果是一样的,是否可以认为第一个复杂度是N^2,第二个是N呢
//写法1
for(let i=0;i<n;i++)
{
let m = 0;
for(let j=0;j<4;j++)
{
m+=i+1;
}
console.log(m);
}
//写法2
for(let i=0;i<n;i++)
{
let m = 0;
m+=i+1;
m+=i+1;
m+=i+1;
m+=i+1;
console.log(m);
}