无限极分类查找所有子孙节点的改进算法

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

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

<?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();
?>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值