当前访客身份:游客 [ 登录 | 加入开源中国 ]

代码分享

当前位置:
代码分享 » PHP  » 数据库编程
分享到: 
收藏 +0
14
我们知道很多开源软件的无限分类都是采用递归的算法,但是我们知道递归即浪费时间,又浪费空间(内存),
上次我也分享了个我自己原创的无限分类生成树的方法,一热心php高手网友给我提出了宝贵的建议,我测试了一下,这段代码的时间非常之短,参考: http://www.oschina.net/code/snippet_98719_11296,我再次整理了一下,发现数据库查询出数据之后,我们就已经定好了键值,因而实践中,我们一般会在model中查询出格式化成主键值对应数据的形式,因而我们可以直接用这样的数据,就少了一层循环。代码也非常简洁。
标签: PHP

代码片段(1) [全屏查看所有代码]

1. [文件] 无限分类数据树形格式化 ~ 9KB     下载(555)     跳至 [1] [全屏预览]

<?php

/**
 * 此方法由@Tonton 提供
 * http://my.oschina.net/u/918697
 * @date 2012-12-12 
 */
function genTree5($items) { 
    foreach ($items as $item) 
        $items[$item['pid']]['son'][$item['id']] = &$items[$item['id']]; 
    return isset($items[0]['son']) ? $items[0]['son'] : array(); 
} 

/**
 * 将数据格式化成树形结构
 * @author Xuefen.Tong
 * @param array $items
 * @return array 
 */
function genTree9($items) {
    $tree = array(); //格式化好的树
    foreach ($items as $item)
        if (isset($items[$item['pid']]))
            $items[$item['pid']]['son'][] = &$items[$item['id']];
        else
            $tree[] = &$items[$item['id']];
    return $tree;
}

$items = array(
    1 => array('id' => 1, 'pid' => 0, 'name' => '江西省'),
    2 => array('id' => 2, 'pid' => 0, 'name' => '黑龙江省'),
    3 => array('id' => 3, 'pid' => 1, 'name' => '南昌市'),
    4 => array('id' => 4, 'pid' => 2, 'name' => '哈尔滨市'),
    5 => array('id' => 5, 'pid' => 2, 'name' => '鸡西市'),
    6 => array('id' => 6, 'pid' => 4, 'name' => '香坊区'),
    7 => array('id' => 7, 'pid' => 4, 'name' => '南岗区'),
    8 => array('id' => 8, 'pid' => 6, 'name' => '和兴路'),
    9 => array('id' => 9, 'pid' => 7, 'name' => '西大直街'),
    10 => array('id' => 10, 'pid' => 8, 'name' => '东北林业大学'),
    11 => array('id' => 11, 'pid' => 9, 'name' => '哈尔滨工业大学'),
    12 => array('id' => 12, 'pid' => 8, 'name' => '哈尔滨师范大学'),
    13 => array('id' => 13, 'pid' => 1, 'name' => '赣州市'),
    14 => array('id' => 14, 'pid' => 13, 'name' => '赣县'),
    15 => array('id' => 15, 'pid' => 13, 'name' => '于都县'),
    16 => array('id' => 16, 'pid' => 14, 'name' => '茅店镇'),
    17 => array('id' => 17, 'pid' => 14, 'name' => '大田乡'),
    18 => array('id' => 18, 'pid' => 16, 'name' => '义源村'),
    19 => array('id' => 19, 'pid' => 16, 'name' => '上坝村'),
);
echo "<pre>";
print_r(genTree5($items));
print_r(genTree9($items));

//后者输出格式,前者类似,只是数组键值不一样,不过不影响数据结构
/*
Array
(
[0] => Array
    (
        [id] => 1
        [pid] => 0
        [name] => 江西省
        [son] => Array
            (
                [0] => Array
                    (
                        [id] => 3
                        [pid] => 1
                        [name] => 南昌市
                    )

                [1] => Array
                    (
                        [id] => 13
                        [pid] => 1
                        [name] => 赣州市
                        [son] => Array
                            (
                                [0] => Array
                                    (
                                        [id] => 14
                                        [pid] => 13
                                        [name] => 赣县
                                        [son] => Array
                                            (
                                            [0] => Array
                                                (
                                                    [id] => 16
                                                    [pid] => 14
                                                    [name] => 茅店镇
                                                    [son] => Array
                                                        (
                                                        [0] => Array
                                                            (
                                                            [id] => 18
                                                            [pid] => 16
                                                            [name] => 义源村
                                                            )

                                                        [1] => Array
                                                            (
                                                            [id] => 19
                                                            [pid] => 16
                                                            [name] => 上坝村
                                                            )

                                                        )

                                                )

                                            [1] => Array
                                                (
                                                    [id] => 17
                                                    [pid] => 14
                                                    [name] => 大田乡
                                                )

                                            )

                                    )

                                [1] => Array
                                    (
                                        [id] => 15
                                        [pid] => 13
                                        [name] => 于都县
                                    )

                            )

                    )

            )

    )

[1] => Array
    (
        [id] => 2
        [pid] => 0
        [name] => 黑龙江省
        [son] => Array
            (
                [0] => Array
                    (
                        [id] => 4
                        [pid] => 2
                        [name] => 哈尔滨市
                        [son] => Array
                            (
                            [0] => Array
                                (
                                    [id] => 6
                                    [pid] => 4
                                    [name] => 香坊区
                                    [son] => Array
                                        (
                                        [0] => Array
                                            (
                                                [id] => 8
                                                [pid] => 6
                                                [name] => 和兴路
                                                [son] => Array
                                                    (
                                                        [0] => Array
                                                            (
                                                            [id] => 10
                                                            [pid] => 8
                                                            [name] => 
                                                             东北林业大学
                                                            )

                                                        [1] => Array
                                                            (
                                                            [id] => 12
                                                            [pid] => 8
                                                            [name] => 
                                                            哈尔滨师范大学
                                                            )

                                                    )

                                            )

                                        )

                                )

                            [1] => Array
                                (
                                    [id] => 7
                                    [pid] => 4
                                    [name] => 南岗区
                                    [son] => Array
                                        (
                                        [0] => Array
                                            (
                                            [id] => 9
                                            [pid] => 7
                                            [name] => 西大直街
                                            [son] => Array
                                                (
                                                [0] => Array
                                                    (
                                                    [id] => 11
                                                    [pid] => 9
                                                    [name] => 
                                                     哈尔滨工业大学
                                                    )

                                                )

                                            )

                                        )

                                )

                            )

                    )

                [1] => Array
                    (
                        [id] => 5
                        [pid] => 2
                        [name] => 鸡西市
                    )

            )

    )
)*/


开源中国-程序员在线工具:Git代码托管 API文档大全(120+) JS在线编辑演示 二维码 更多»

发表评论 回到顶部 网友评论(94)

  • 1楼:酒逍遥 发表于 2012-09-11 14:47 回复此评论
    思路不错...关键是就是 引用的 使用..
  • 2楼:红科 发表于 2012-11-03 11:20 回复此评论
    有点晕。。的好好看看php引用
  • 3楼:爬墙 发表于 2013-01-02 01:33 回复此评论
    得到了数组,要想用得到的数组以自己想要的格式输出还得递归吧?
  • 4楼:童学芬 发表于 2012-11-03 12:29 回复此评论

    引用来自“rocke”的评论

    有点晕。。的好好看看php引用
    所有语言的引用都是一样的道理
  • 5楼:cooc123 发表于 2013-01-02 11:11 回复此评论
    格式化后的数组打印出来不还是要递归的呀
  • 6楼:水牛叔叔 发表于 2013-01-02 17:06 回复此评论
    其实递归的展示用递归倒不是很糟,但是递归地去数据库取数据才是最糟糕的。要是有人能有办法不用递归,就能从数据库里取得无限级分类的数据就牛逼了
  • 7楼:山哥 发表于 2013-01-02 22:54 回复此评论

    引用来自“1inus”的评论

    其实递归的展示用递归倒不是很糟,但是递归地去数据库取数据才是最糟糕的。要是有人能有办法不用递归,就能从数据库里取得无限级分类的数据就牛逼了
    我们惯性设计树形结构都是 id pid结构的,要想彻底放弃递归等而直接读取就是树形结构,那就要改变我们的一贯设计方式,采用多叉树方式: http://www.phpro.org/tutorials/Managing-Hierarchical-Data-with-PHP-and-MySQL.html
  • 8楼:山哥 发表于 2013-01-02 22:57 回复此评论

    引用来自“童学芬”的评论

    引用来自“Tonton”的评论

    五行代码就可以了. 修改为:

    function genTree($items) {
        foreach ($items as $item)
            $items[$item['pid']]['son'][$item['id']] = &$items[$item['id']];
        return isset($items[0]['son']) ? $items[0]['son'] : array();
    }
    高手,高手,看来我这是标题党了。哈哈
    这个如果转为Java能做到吗?
  • 9楼:水牛叔叔 发表于 2013-01-03 00:02 回复此评论

    引用来自“JSON”的评论

    引用来自“1inus”的评论

    其实递归的展示用递归倒不是很糟,但是递归地去数据库取数据才是最糟糕的。要是有人能有办法不用递归,就能从数据库里取得无限级分类的数据就牛逼了
    我们惯性设计树形结构都是 id pid结构的,要想彻底放弃递归等而直接读取就是树形结构,那就要改变我们的一贯设计方式,采用多叉树方式: http://www.phpro.org/tutorials/Managing-Hierarchical-Data-with-PHP-and-MySQL.html
    嗯,这个值得去看看
  • 10楼:th小米粥 发表于 2012-09-13 14:06 回复此评论
    看不懂php...
  • 11楼:李惟 发表于 2012-11-04 19:50 回复此评论

    引用来自“赵祖辉”的评论

    不过思路挺好 收藏再研究
    楼主这个是根据PID来排的,如果排序前不确定顺序的话,可以给数组先排序
  • 12楼:暮雨行舟 发表于 2013-01-03 12:33 回复此评论
    不错
  • 13楼:口米巴 发表于 2013-01-03 20:13 回复此评论
    一味地追求简洁,牺牲了一定的代码可读性  如果代码是跟团队合作的,我觉得反而可读性更加重要
  • 14楼:poppub 发表于 2012-11-05 09:35 回复此评论
    收藏
  • 15楼:jingdor 发表于 2013-01-03 23:22 回复此评论

    引用来自“1inus”的评论

    其实递归的展示用递归倒不是很糟,但是递归地去数据库取数据才是最糟糕的。要是有人能有办法不用递归,就能从数据库里取得无限级分类的数据就牛逼了
    xml
  • 16楼:~\(≧▽≦)/~ 发表于 2012-11-05 10:25 回复此评论

    引用来自“赵祖辉”的评论

    还是有点问题,如果不是从父开始 那就会出现短链的情况,或者数据库出现断链情况 那就又是问题
    换个思路,取数据的时候pid排序
  • 17楼:农夫软件 发表于 2012-11-05 14:32 回复此评论
    还不错。
  • 18楼:小扈 发表于 2012-11-05 15:24 回复此评论
    看了之后好想学php呀,问一下,php和js差别大吗
  • 19楼:haitao 发表于 2012-11-05 16:14 回复此评论

    代码没递归,系统(解释器)的运行实现还是递归了吧?
    真正无须递归而生成树的办法,需要修改树的结构(属性、字段)

  • 20楼:蛮大人 发表于 2013-01-04 11:49 回复此评论
    Java的JPA有更经典的设计。(参考传智播客黎活明的巴巴运动网教程)
    融入面向对象,代码更奇妙。
    并不是越少越好。