zoukankan      html  css  js  c++  java
  • 迭代与递归实现无限级分类

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

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

  • 相关阅读:
    30张图解: TCP 重传、滑动窗口、流量控制、拥塞控制
    ffmpeg rtp时间戳
    35 张图解:被问千百遍的 TCP 三次握手和四次挥手面试题
    Pinpoint 分布式系统性能监控工具
    图解正向代理、反向代理、透明代理
    实战!我用 Wireshark 让你“看见“ TCP
    IE7的增强插件:IE7Pro
    Net Core 中的HTTP协议详解
    Autofac是一个轻量级的依赖注入的框架
    关于表数据的复制插入TSQL
  • 原文地址:https://www.cnblogs.com/phpper/p/7446275.html
Copyright © 2011-2022 走看看