无限级分类是开发中常见的情况了,在这里我收藏了下并整理了下常见的无限极分类算法总结归纳.
<?php $arr = [ 1=>[\'id\'=>1,\'name\'=>\'家居\',\'father\'=>NULL], 2=>[\'id\'=>2,\'name\'=>\'服装\',\'father\'=>NULL], 3=>[\'id\'=>3,\'name\'=>\'护肤品\',\'father\'=>NULL], 4=>[\'id\'=>4,\'name\'=>\'生活日用\',\'father\'=>1], 5=>[\'id\'=>5,\'name\'=>\'家庭装修\',\'father\'=>1], 6=>[\'id\'=>6,\'name\'=>\'厨房卫浴\',\'father\'=>1], 7=>[\'id\'=>7,\'name\'=>\'男装\',\'father\'=>2], 8=>[\'id\'=>8,\'name\'=>\'女装\',\'father\'=>2], 9=>[\'id\'=>9,\'name\'=>\'面部护肤\',\'father\'=>3], 10=>[\'id\'=>10,\'name\'=>\'补水保湿\',\'father\'=>9], 11=>[\'id\'=>11,\'name\'=>\'收纳用品\',\'father\'=>4], 12=>[\'id\'=>12,\'name\'=>\'牛仔裤\',\'father\'=>7], ]; function generateTree($items){ $tree = array(); foreach($items as $item){ if(isset($items[$item[\'father\']])){ $items[$item[\'father\']][\'son\'][] = &$items[$item[\'id\']]; }else{ $tree[] = &$items[$item[\'id\']]; } } return $tree; } $tree = generateTree($arr); print_r($tree); ?>
输出:
Array ( [0] => Array ( [id] => 1 [name] => 家居 [father] => [son] => Array ( [0] => Array ( [id] => 4 [name] => 生活日用 [father] => 1 [son] => Array ( [0] => Array ( [id] => 11 [name] => 收纳用品 [father] => 4 ) ) ) [1] => Array ( [id] => 5 [name] => 家庭装修 [father] => 1 ) [2] => Array ( [id] => 6 [name] => 厨房卫浴 [father] => 1 ) ) ) [1] => Array ( [id] => 2 [name] => 服装 [father] => [son] => Array ( [0] => Array ( [id] => 7 [name] => 男装 [father] => 2 [son] => Array ( [0] => Array ( [id] => 12 [name] => 牛仔裤 [father] => 7 ) ) ) [1] => Array ( [id] => 8 [name] => 女装 [father] => 2 ) ) ) [2] => Array ( [id] => 3 [name] => 护肤品 [father] => [son] => Array ( [0] => Array ( [id] => 9 [name] => 面部护肤 [father] => 3 [son] => Array ( [0] => Array ( [id] => 10 [name] => 补水保湿 [father] => 9 ) ) ) ) ) )
分析:
这个算法利用了循环迭代,将线性结构按照父子关系以树形结构输出,算法的关键在于使用了引用.
优点:速度快,效率高.
缺点:数组的key值必须与id值相同,不便于取出数据(使用递归获取数据)
我们再看下递归的实现:
<?php $arr = [ 1=>[\'id\'=>1,\'name\'=>\'家居\',\'father\'=>NULL], 2=>[\'id\'=>2,\'name\'=>\'服装\',\'father\'=>NULL], 3=>[\'id\'=>3,\'name\'=>\'护肤品\',\'father\'=>NULL], 4=>[\'id\'=>4,\'name\'=>\'生活日用\',\'father\'=>1], 5=>[\'id\'=>5,\'name\'=>\'家庭装修\',\'father\'=>1], 6=>[\'id\'=>6,\'name\'=>\'厨房卫浴\',\'father\'=>1], 7=>[\'id\'=>7,\'name\'=>\'男装\',\'father\'=>2], 8=>[\'id\'=>8,\'name\'=>\'女装\',\'father\'=>2], 9=>[\'id\'=>9,\'name\'=>\'面部护肤\',\'father\'=>3], 10=>[\'id\'=>10,\'name\'=>\'补水保湿\',\'father\'=>9], 11=>[\'id\'=>11,\'name\'=>\'收纳用品\',\'father\'=>4], 12=>[\'id\'=>12,\'name\'=>\'牛仔裤\',\'father\'=>7], ]; function generateTree($arr,$id,$step){ static $tree=[]; foreach($arr as $key=>$val) { if($val[\'father\'] == $id) { $flag = str_repeat(\'└―\',$step); $val[\'name\'] = $flag.$val[\'name\']; $tree[] = $val; generateTree($arr , $val[\'id\'] ,$step+1); } } return $tree; } $tree = generateTree($arr,0,0); foreach ($tree as $val){ echo $val[\'name\'].\'<br>\'; } ?>
输出:
家居
└―生活日用
└―└―收纳用品
└―家庭装修
└―厨房卫浴
服装
└―男装
└―└―牛仔裤
└―女装
护肤品
└―面部护肤
└―└―补水保湿
分析:
利用了递归,数组的key值与id值可以不相同,最后以顺序的结构输出数组
优点:方便遍历,查找父子元素
缺点:php不擅长递归,数据量大的情况下效率会显著降低
总结:两种方法各有利弊,后者不适合大数据下使用,前者推荐吧