php无限分类形成列表树并显示子栏目总数

<pre name="code" class="php"><pre name="code" class="php"><?php
	$arr = array(
		array('id' => 111, 'pid' => 0, 'name' => '江西省'),
		array('id' => 5, 'pid' => 2, 'name' => '鸡西市'),
		array('id' => 2, 'pid' => 0, 'name' => '黑龙江省'),
		array('id' => 3, 'pid' => 111, 'name' => '南昌市'),
		array('id' => 6, 'pid' => 4, 'name' => '香坊区'),
		array('id' => 27, 'pid' => 4, 'name' => '南岗区'),
		array('id' => 8, 'pid' => 6, 'name' => '和兴路'),
		array('id' => 9, 'pid' => 27, 'name' => '西大直街'),
		array('id' => 10, 'pid' => 8, 'name' => '东北林业大学'),
		array('id' => 11, 'pid' => 9, 'name' => '哈尔滨工业大学'),
		array('id' => 12, 'pid' => 8, 'name' => '哈尔滨师范大学'),
		array('id' => 13, 'pid' => 111, 'name' => '赣州市'),
		array('id' => 14, 'pid' => 13, 'name' => '赣县'),
		array('id' => 15, 'pid' => 13, 'name' => '于都县'),
		array('id' => 16, 'pid' => 14, 'name' => '茅店镇'),
		array('id' => 17, 'pid' => 14, 'name' => '大田乡'),
		array('id' => 18, 'pid' => 16, 'name' => '义源村'),
		array('id' => 19, 'pid' => 16, 'name' => '上坝村')
	);
	static $_arr2 = array();       //用于存放整理好的数据
	/**
	 * 对数组按照子父类顺序整理,并且直接获取栏目的所有子栏目数
	 * @param array $_arr2 用于存放整理结果的数组
	 * @param array $arr 需要整理的数组
	 * @param number $pid 父栏目id,会递归找出该父亲栏目下的所有子栏目
	 * @param number $level 第几级
	 * @return array $num 子栏目数
	 */
	function getTreeAndNum(&$_arr2, $arr, $pid=0, $level=0 ,$isClear=FALSE){
	    if($isClear)
	       $_arr2 = array();
	    $num = 0;
	    foreach($arr as $k => $v){
	        if($v['pid'] == $pid){
	            $v['level'] = $level;
	            $_arr2[$v['id']] = $v;
	            $num ++;
	            $allnum = getTreeAndNum($_arr2, $arr, $v['id'], $level+1);
	            $_arr2[$v['id']]['num'] = $allnum;
	            $num = $num + $allnum;
	        }
	    }
	    return $num;
	}
	
	/**
	 * 对数组按照子父类顺序整理
	 * @param array $arr 需要整理的数组
	 * @param number $pid 父栏目id
	 * @param number $level 第几级
	 * @return array $_arr 整理好的数组
	 */
	function getTree($arr, $pid=0, $level=0, $isClear=FALSE){
		//因为不断调用自己的时候,会不断开辟新的空间,空间与空间之间的变量是不能共享的,可//以存放到静态数组中,实现共享
	    static $_arr = array();
	    if($isClear)
	        $_arr = array();
		foreach($arr as $k => $v){
			if($v['pid'] == $pid){
				$v['level'] = $level;
				$_arr[] = $v;
			    getTree($arr, $v['id'], $level+1);
			}
		}
		return $_arr;
	}
    
    /**
     * 获取一个栏目的所有子栏目数
     * @param array $arr 数组
     * @param number $catId 父栏目
     * @return number $_ret 一个栏目的子栏目数
     */
	function getChildrenNums($arr, $catId, $isClear=FALSE)
	{
		static $_ret = 0;  
		if($isClear)
		   $_ret = 0;
		foreach ($arr as $k => $v)
		{
			if($v['pid'] == $catId)
			{
				$_ret++;
				
				getChildrenNums($arr, $v['id']);
			}
		}
		return $_ret;
	}
	/**
	 * 获取列表树,此方法先遍历整理好的数组,在遍历的过程中再次去调用函数获取该栏目的所有子栏目数目
	 * @param unknown $arr 数组
	 */
	function getList($arr){
		
		foreach($arr as $k => $v){
			echo str_repeat('-', 4*$v['level']).$v['name'].'('.getChildrenNums($arr, $v['id'], TRUE).')'.'<br/>';
		}
	}
	
	function getNewList($arr){
	    foreach($arr as $k => $v){
	        echo str_repeat('-', 4*$v['level']).$v['name'].'('.$v['num'].')'.'<br/>';
	    }
	}
	/**
	 * 返回当前的时间,以秒为单位
	 * @return number
	 */
	function getMicTime(){
	    return time();
	}
	
	
	
	/**
	 * 性能测试,由于数据量比较小,循环后才能见到差距,数据量大的话,差距会明显些
	 * 总结来说,方案2的效率会高些
	 */
	echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
	/****************方案1**********************/
	
	$time1 = getMicTime();
	for($i = 0; $i < 4000; $i++){
	    $arr = getTree($arr, $pid=0, $level=0, TRUE);
	    getList($arr);
	}
	$time2 = getMicTime();
	echo '方案1的性能为:'.($time2-$time1).'<br>';
	
	
	/****************方案2**********************/
 	$time3 = getMicTime();
 	for($i = 0; $i < 4000; $i++){
 		getTreeAndNum($_arr2, $arr, $pid=0, $level=0 ,TRUE);
 		getNewList($_arr2);
 	}
 	$time4 = getMicTime();
    echo '方案2的性能为:'.($time4-$time3).'<br>';


 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值