有内循环的算法,复杂度就一定是N^2吗

344 阅读1分钟
是的,
书上是这么说,
一准,不会错

但,我想说
要思考,思考特殊情况
是否存在

列表转树

在实际开发中,像多级菜单、省市区联动等在客户端的结构一般为树状结构。

[
    {
        id:1,
        name:'北京'parentId:0,
        children:[
            
            {
                id:2,
                name:'海淀区',
                parentId:1,
                children:[
                    
                    {
                        id:3,
                        name:'上庄镇',
                        parentId:2
                    }
                ]
            }
        ]
    }
]

这类数据在服务端存储时却是下述这样的二维表,如果服务端人员很懒,没有进行转换,而是直接把数据原样扔了过来,那我们就只能自己进行转换了。

idnameparentId
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);
}

性能测试

www.npmjs.com/package/fas…

image.png