迭代与递归实现无限级分类

无限级分类是开发中常见的情况了,在这里我收藏了下并整理了下常见的无限极分类算法总结归纳.

<?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不擅长递归,数据量大的情况下效率会显著降低
总结:两种方法各有利弊,后者不适合大数据下使用,前者推荐吧

原文地址:https://www.cnblogs.com/phpper/p/7446275.html