zoukankan      html  css  js  c++  java
  • 无限极分类查找所有子孙节点的改进算法

    在以前,遇到无限极分类返回一个节点的所有子孙节点时,我都是用递归计算的,后来发现时间复杂度和空间复杂度都太高了,后来自己研究了一下改进了算法.

    节点数据如下:键值对分别是自己对应父亲节点

    <?php
    $tree=array(
        1=>0,
        2=>1,
        3=>2,
        4=>3,
        5=>4,
        6=>5,
        7=>6,
        8=>7,
        9=>8,
        10=>9,
        11=>10,
        12=>11,
        13=>12,
        14=>13,
        15=>14,
        16=>15,
        17=>16,
        18=>17,
        19=>18,
        20=>19,
        21=>20,
        22=>21,
        23=>22,
        24=>23,
        25=>24,
        26=>25,
        27=>26,
        28=>27,
        29=>28,
        30=>29,
        31=>30,
        32=>31,
        33=>32,
        34=>33,
        35=>34,
        36=>35,
        37=>36,
        38=>37,
        39=>38,
        40=>39,
        41=>40,
        42=>41,
        43=>42,
        44=>43,
        45=>44,
        46=>45,
        47=>46,
        48=>47,
        49=>48,
        50=>49,
        51=>50,
        52=>51,
        53=>52,
        54=>53,
        55=>54,
        56=>55,
        57=>56,
        58=>57,
        59=>58,
        60=>59,
        61=>60,
        62=>61,
        63=>62,
        64=>63,
        65=>64,
        66=>65,
        67=>66,
        68=>67,
        69=>68,
        70=>69,
        71=>70,
        72=>71,
        73=>72,
        74=>73,
        75=>74,
        76=>75,
        77=>76,
        78=>77,
        79=>78,
        80=>79,
        81=>80,
        82=>81,
        83=>82,
        84=>83,
        85=>84,
        86=>85,
        87=>86,
        88=>87,
        89=>88,
        90=>89,
        91=>90,
        92=>91,
        93=>92,
        94=>93,
        95=>94,
        96=>95,
        97=>96,
        98=>97,
        99=>98,
        100=>99,//如果是递归的方法 到这一层的时候 就报错了 可以注释该层
    );
    ?>

    以往算法如下:

    <?php
    function get_list($tree,$id=0)
    {
        static $list=array();//定义静态数组存放子孙
        foreach ($tree as $key => $v) 
        {
            if($v==$id)
            {
                $list[]=$key;//把子孙放入数组中
                unset($tree[$key]);//去掉这个数组的键 避免无效循环
                get_list($tree,$key);//再次调用自身,把子节点变成父节点去寻找子孙
            }
        }
        return $list;//返回数组
    }
    ?>

     结果如图

    去掉最后一层的那个元素 就可以获取了。

    这说明这样的算法在遇到节点层级非常深的时候会崩溃,例如超过100层,php会报错误的。后来改进了一种算法如下:

    <?php
    $id=2;
    
    $new_array=array();//存放子孙的数组
    $id_list[]=$id;//存放父亲的数组
    //遍历所有子孙数据 每次去取已经有的数据的子孙 并把它加入父亲数组
    for ($i=1; $i <= count($tree); $i++) 
    { 
        foreach ($tree as $key => $v) 
        {
            if( in_array($v,$id_list) ) 
            {
                $new_array[$key]=$v;//把我放进子孙数组
                $id_list[$key]=$key;//把子孙也放入父亲数组
                unset($tree[$key]);//这个已经用过了可以回收了避免无效循环
            }
        }
    }
    $son_list=array_keys($new_array);//拿到存放子孙的数组 取键即可
    print_r($son_list);
    exit();
    ?>
  • 相关阅读:
    波卡(Polkadot)创始人Gavin Wood眼中加密世界
    DOT的目的是什么
    如何在波卡测试网上起验证人节点
    Polkadot波卡链众筹成本价与总量、创始人团队简介
    Polkadot验证节点的安全性和可用性
    RSA算法详解
    haproxy+keepalived原理特点
    haproxy+keepalived原理特点
    haproxy+keepalived原理特点
    python基础1习题练习
  • 原文地址:https://www.cnblogs.com/lizhaoyao/p/5843002.html
Copyright © 2011-2022 走看看