无限分类 递归

简介:
在所有栏目、地区等 下拉菜单中,这个类非常好用

 
Java代码   收藏代码
  1. <?php  
  2. include("tree.class.php");  
  3. //具有这个结构的数组,不是这样的话,可以改类的实现  
  4.   
  5. $list = array(  
  6.     1 => array('id' => '1''pid' => 0'name' => '一级栏目一'),  
  7.     2 => array('id' => '2''pid' => 0'name' => '一级栏目二'),  
  8.     3 => array('id' => '3''pid' => 1'name' => '二级栏目一'),  
  9.     4 => array('id' => '4''pid' => 1'name' => '二级栏目二'),  
  10.     5 => array('id' => '5''pid' => 2'name' => '二级栏目三'),  
  11.     6 => array('id' => '6''pid' => 3'name' => '三级栏目一'),  
  12.     7 => array('id' => '7''pid' => 3'name' => '三级栏目二')  
  13. );  
  14.   
  15. $tree = new tree($list);  
  16. $html = "<select name='cat'>";  
  17. $str = "<option value=\$id \$selected>\$spacer\$name</option>";  
  18. $html .= $tree->get_tree(0, $str);  
  19. $html .= "</select>";  
  20.   
  21. echo($html);  
  22. ?>  

 tree.class.php

Java代码   收藏代码
  1. <?php  
  2. /** 
  3. * 通用的树型类,可以生成任何树型结构 
  4. */  
  5. class tree {  
  6.     /** 
  7.     * 生成树型结构所需要的2维数组 
  8.     * @var array 
  9.     */  
  10.     public $arr = array();  
  11.   
  12.     /** 
  13.     * 生成树型结构所需修饰符号,可以换成图片 
  14.     * @var array 
  15.     */  
  16.     public $icon = array('│','├','└');  
  17.     public $nbsp = "&nbsp;";  
  18.   
  19.     /** 
  20.     * @access private 
  21.     */  
  22.     public $ret = '';  
  23.   
  24.     /** 
  25.     * 构造函数,初始化类 
  26.     * @param array 2维数组,例如: 
  27.     * array( 
  28.     *      1 => array('id'=>'1','parentid'=>0,'name'=>'一级栏目一'), 
  29.     *      2 => array('id'=>'2','parentid'=>0,'name'=>'一级栏目二'), 
  30.     *      3 => array('id'=>'3','parentid'=>1,'name'=>'二级栏目一'), 
  31.     *      4 => array('id'=>'4','parentid'=>1,'name'=>'二级栏目二'), 
  32.     *      5 => array('id'=>'5','parentid'=>2,'name'=>'二级栏目三'), 
  33.     *      6 => array('id'=>'6','parentid'=>3,'name'=>'三级栏目一'), 
  34.     *      7 => array('id'=>'7','parentid'=>3,'name'=>'三级栏目二') 
  35.     *      ) 
  36.     */  
  37.     public function __construct($arr=array()){  
  38.        $this->arr = $arr;  
  39.        $this->ret = '';  
  40.        return is_array($arr);  
  41.     }  
  42.   
  43.     /** 
  44.     * 得到父级数组 
  45.     * @param int 
  46.     * @return array 
  47.     */  
  48.     public function get_parent($myid){  
  49.         $newarr = array();  
  50.         if(!isset($this->arr[$myid])) return false;  
  51.         $pid = $this->arr[$myid]['parentid'];  
  52.         $pid = $this->arr[$pid]['parentid'];  
  53.         if(is_array($this->arr)){  
  54.             foreach($this->arr as $id => $a){  
  55.                 if($a['parentid'] == $pid) $newarr[$id] = $a;  
  56.             }  
  57.         }  
  58.         return $newarr;  
  59.     }  
  60.   
  61.     /** 
  62.     * 得到子级数组 
  63.     * @param int 
  64.     * @return array 
  65.     */  
  66.     public function get_child($myid){  
  67.         $a = $newarr = array();  
  68.         if(is_array($this->arr)){  
  69.             foreach($this->arr as $id => $a){  
  70.                 if($a['parentid'] == $myid) $newarr[$id] = $a;  
  71.             }  
  72.         }  
  73.         return $newarr ? $newarr : false;  
  74.     }  
  75.   
  76.     /** 
  77.     * 得到当前位置数组 
  78.     * @param int 
  79.     * @return array 
  80.     */  
  81.     public function get_pos($myid,&$newarr){  
  82.         $a = array();  
  83.         if(!isset($this->arr[$myid])) return false;  
  84.         $newarr[] = $this->arr[$myid];  
  85.         $pid = $this->arr[$myid]['parentid'];  
  86.         if(isset($this->arr[$pid])){  
  87.             $this->get_pos($pid,$newarr);  
  88.         }  
  89.         if(is_array($newarr)){  
  90.             krsort($newarr);  
  91.             foreach($newarr as $v){  
  92.                 $a[$v['id']] = $v;  
  93.             }  
  94.         }  
  95.         return $a;  
  96.     }  
  97.   
  98.     /** 
  99.     * 得到树型结构 
  100.     * @param int ID,表示获得这个ID下的所有子级 
  101.     * @param string 生成树型结构的基本代码,例如:"<option value=\$id \$selected>\$spacer\$name</option>" 
  102.     * @param int 被选中的ID,比如在做树型下拉框的时候需要用到 
  103.     * @return string 
  104.     */  
  105.     public function get_tree($myid, $str, $sid = 0, $adds = '', $str_group = ''){  
  106.         $number=1;  
  107.         $child = $this->get_child($myid);  
  108.         if(is_array($child)){  
  109.             $total = count($child);  
  110.             foreach($child as $id=>$value){  
  111.                 $j=$k='';  
  112.                 if($number==$total){  
  113.                     $j .= $this->icon[2];  
  114.                 }else{  
  115.                     $j .= $this->icon[1];  
  116.                     $k = $adds ? $this->icon[0] : '';  
  117.                 }  
  118.                 $spacer = $adds ? $adds.$j : '';  
  119.                 $selected = $id==$sid ? 'selected' : '';  
  120.                 @extract($value);  
  121.                 $parentid == 0 && $str_group ? eval("\$nstr = \"$str_group\";") : eval("\$nstr = \"$str\";");  
  122.                 $this->ret .= $nstr;  
  123.                 $nbsp = $this->nbsp;  
  124.                 $this->get_tree($id, $str, $sid, $adds.$k.$nbsp,$str_group);  
  125.                 $number++;  
  126.             }  
  127.         }  
  128.         return $this->ret;  
  129.     }  
  130.     /** 
  131.     * 同上一方法类似,但允许多选 
  132.     */  
  133.     public function get_tree_multi($myid, $str, $sid = 0, $adds = ''){  
  134.         $number=1;  
  135.         $child = $this->get_child($myid);  
  136.         if(is_array($child)){  
  137.             $total = count($child);  
  138.             foreach($child as $id=>$a){  
  139.                 $j=$k='';  
  140.                 if($number==$total){  
  141.                     $j .= $this->icon[2];  
  142.                 }else{  
  143.                     $j .= $this->icon[1];  
  144.                     $k = $adds ? $this->icon[0] : '';  
  145.                 }  
  146.                 $spacer = $adds ? $adds.$j : '';  
  147.                   
  148.                 $selected = $this->have($sid,$id) ? 'selected' : '';  
  149.                 @extract($a);  
  150.                 eval("\$nstr = \"$str\";");  
  151.                 $this->ret .= $nstr;  
  152.                 $this->get_tree_multi($id, $str, $sid, $adds.$k.'&nbsp;');  
  153.                 $number++;  
  154.             }  
  155.         }  
  156.         return $this->ret;  
  157.     }  
  158.      /** 
  159.     * @param integer $myid 要查询的ID 
  160.     * @param string $str   第一种HTML代码方式 
  161.     * @param string $str2  第二种HTML代码方式 
  162.     * @param integer $sid  默认选中 
  163.     * @param integer $adds 前缀 
  164.     */  
  165.     public function get_tree_category($myid, $str, $str2, $sid = 0, $adds = ''){  
  166.         $number=1;  
  167.         $child = $this->get_child($myid);  
  168.         if(is_array($child)){  
  169.             $total = count($child);  
  170.             foreach($child as $id=>$a){  
  171.                 $j=$k='';  
  172.                 if($number==$total){  
  173.                     $j .= $this->icon[2];  
  174.                 }else{  
  175.                     $j .= $this->icon[1];  
  176.                     $k = $adds ? $this->icon[0] : '';  
  177.                 }  
  178.                 $spacer = $adds ? $adds.$j : '';  
  179.                   
  180.                 $selected = $this->have($sid,$id) ? 'selected' : '';  
  181.                 @extract($a);  
  182.                 if (empty($html_disabled)) {  
  183.                     eval("\$nstr = \"$str\";");  
  184.                 } else {  
  185.                     eval("\$nstr = \"$str2\";");  
  186.                 }  
  187.                 $this->ret .= $nstr;  
  188.                 $this->get_tree_category($id, $str, $str2, $sid, $adds.$k.'&nbsp;');  
  189.                 $number++;  
  190.             }  
  191.         }  
  192.         return $this->ret;  
  193.     }  
  194.       
  195.     /** 
  196.      * 同上一类方法,jquery treeview 风格,可伸缩样式(需要treeview插件支持) 
  197.      * @param $myid 表示获得这个ID下的所有子级 
  198.      * @param $effected_id 需要生成treeview目录数的id 
  199.      * @param $str 末级样式 
  200.      * @param $str2 目录级别样式 
  201.      * @param $showlevel 直接显示层级数,其余为异步显示,0为全部限制 
  202.      * @param $style 目录样式 默认 filetree 可增加其他样式如'filetree treeview-famfamfam' 
  203.      * @param $currentlevel 计算当前层级,递归使用 适用改函数时不需要用该参数 
  204.      * @param $recursion 递归使用 外部调用时为FALSE 
  205.      */  
  206.     function get_treeview($myid,$effected_id='example',$str="<span class='file'>\$name</span>", $str2="<span class='folder'>\$name</span>" ,$showlevel = 0 ,$style='filetree ' , $currentlevel = 1,$recursion=FALSE) {  
  207.         $child = $this->get_child($myid);  
  208.         if(!defined('EFFECTED_INIT')){  
  209.            $effected = ' id="'.$effected_id.'"';  
  210.            define('EFFECTED_INIT'1);  
  211.         } else {  
  212.            $effected = '';  
  213.         }  
  214.         $placeholder =  '<ul><li><span class="placeholder"></span></li></ul>';  
  215.         if(!$recursion) $this->str .='<ul'.$effected.'  class="'.$style.'">';  
  216.         foreach($child as $id=>$a) {  
  217.   
  218.             @extract($a);  
  219.             if($showlevel > 0 && $showlevel == $currentlevel && $this->get_child($id)) $folder = 'hasChildren'//如设置显示层级模式@2011.07.01  
  220.             $floder_status = isset($folder) ? ' class="'.$folder.'"' : '';        
  221.             $this->str .= $recursion ? '<ul><li'.$floder_status.' id=\''.$id.'\'>' : '<li'.$floder_status.' id=\''.$id.'\'>';  
  222.             $recursion = FALSE;  
  223.             if($this->get_child($id)){  
  224.                 eval("\$nstr = \"$str2\";");  
  225.                 $this->str .= $nstr;  
  226.                 if($showlevel == 0 || ($showlevel > 0 && $showlevel > $currentlevel)) {  
  227.                     $this->get_treeview($id, $effected_id, $str, $str2, $showlevel, $style, $currentlevel+1, TRUE);  
  228.                 } elseif($showlevel > 0 && $showlevel == $currentlevel) {  
  229.                     $this->str .= $placeholder;  
  230.                 }  
  231.             } else {  
  232.                 eval("\$nstr = \"$str\";");  
  233.                 $this->str .= $nstr;  
  234.             }  
  235.             $this->str .=$recursion ? '</li></ul>''</li>';  
  236.         }  
  237.         if(!$recursion)  $this->str .='</ul>';  
  238.         return $this->str;  
  239.     }  
  240.       
  241.     /** 
  242.      * 获取子栏目json 
  243.      * Enter description here ... 
  244.      * @param unknown_type $myid 
  245.      */  
  246.     public function creat_sub_json($myid, $str='') {  
  247.         $sub_cats = $this->get_child($myid);  
  248.         $n = 0;  
  249.         if(is_array($sub_cats)) foreach($sub_cats as $c) {            
  250.             $data[$n]['id'] = iconv(CHARSET,'utf-8',$c['catid']);  
  251.             if($this->get_child($c['catid'])) {  
  252.                 $data[$n]['liclass'] = 'hasChildren';  
  253.                 $data[$n]['children'] = array(array('text'=>'&nbsp;','classes'=>'placeholder'));  
  254.                 $data[$n]['classes'] = 'folder';  
  255.                 $data[$n]['text'] = iconv(CHARSET,'utf-8',$c['catname']);  
  256.             } else {                  
  257.                 if($str) {  
  258.                     @extract(array_iconv($c,CHARSET,'utf-8'));  
  259.                     eval("\$data[$n]['text'] = \"$str\";");  
  260.                 } else {  
  261.                     $data[$n]['text'] = iconv(CHARSET,'utf-8',$c['catname']);  
  262.                 }  
  263.             }  
  264.             $n++;  
  265.         }  
  266.         return json_encode($data);        
  267.     }  
  268.     private function have($list,$item){  
  269.         return(strpos(',,'.$list.',',','.$item.','));  
  270.     }  
  271. }  
  272. /** 
  273.  * +------------------------------------------------ 
  274.  * 格式化数组 
  275.  * +------------------------------------------------ 
  276.  */  
  277. function getArray($myid = 0, $sid = 0, $adds = '') {  
  278.     $number = 1;  
  279.     $child = $this->get_child($myid);  
  280.     if (is_array($child)) {  
  281.         $total = count($child);  
  282.         foreach ($child as $id => $a) {  
  283.             $j = $k = '';  
  284.             if ($number == $total) {  
  285.                 $j .= $this->icon[2];  
  286.             } else {  
  287.                 $j .= $this->icon[1];  
  288.                 $k = $adds ? $this->icon[0] : '';  
  289.             }  
  290.             $spacer = $adds ? $adds . $j : '';  
  291.             @extract($a);  
  292.             $a[$name] = $spacer . $a[$name];  
  293.             $this->ret[$a[$id]] = $a;  
  294.             $fd = $adds . $k . $this->nbsp;  
  295.             $this->getArray($id, $sid, $fd);  
  296.             $number++;  
  297.         }  
  298.     }  
  299.   
  300.     return $this->ret;  
  301. }  
  302. ?>  

递归实现层级树状展现数据

Java代码   收藏代码
  1. <?php  
  2. // 将数据按照所属关系封装 见图2  
  3. function arr2tree($tree, $rootId = 0, $idName='id', $parentIdName='pid') {  
  4.     $return = array();  
  5.     foreach ($tree as $leaf) {  
  6.         if ($leaf[$parentIdName] == $rootId) {  
  7.             foreach ($tree as $subleaf) {  
  8.                 if ($subleaf[$parentIdName] == $leaf[$idName]) {  
  9.                     $leaf['children'] = arr2tree($tree, $leaf[$idName]);  
  10.                     break;  
  11.                 }  
  12.             }  
  13.             $return[] = $leaf;  
  14.         }  
  15.     }  
  16.     return $return;  
  17. }  
  18.   
  19. $tree = arr2tree($data);  
  20. print_r($tree);  
  21. echo '<br/>-----------------------------------------------------------------------<br/>';  
  22.   
  23. // 将数据使用HTML再次展现 见图3  
  24. function tree2html($tree) {  
  25.     echo '<ul>';  
  26.     foreach ($tree as $leaf) {  
  27.         echo '<li>' . $leaf['name'];  
  28.         if (!empty($leaf['children'])) tree2html($leaf['children']);  
  29.         echo '</li>';  
  30.     }  
  31.     echo '</ul>';  
  32. }  
  33.   
  34. tree2html($tree);  
相关文章
|
5月前
|
JavaScript 前端开发
什么是递归?
什么是递归?
41 0
|
11月前
|
机器学习/深度学习 BI
递归问题
递归问题
|
机器学习/深度学习
什么是递归
通过阶乘函数f(n)=n! f(0)=1 f(n)=f(n-1)*n(n>=1)简要理解递归
74 0
|
算法 索引
第 6 章 递归
简单的说: 递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。
52 0
|
存储 Serverless 开发者
递归的理解与实现
递归的理解与实现
递归的理解与实现
|
机器学习/深度学习 算法
『递归』整数划分
根据n和m的关系,考虑一下几种情况: (一)当n==1时,无论m的值为多少 ,只有一种划分,即{1} (二)当m==1 时,无论n的值为多少,只有一种划分,即1个n,{n} 。 (三)当n==m时,根据划分中是否包含n,可以分为以下两种情况: (1)划分中包含n的情况,只有一个,即 {n} (2)划分中不包含n的情况,这时划分中最大的数字也一定比n小,即n的所有(n-1)划分,即q(n,n-1)。 因此q(n,m)=1+q(n,n-1) (四)当n<m时,由于划分中不可能出现负数,因此就相当于q(n,n) (五)当n>m 时,根据划分中是否包含最大值m,可以分为以下两种情况:
129 0
递归就是这么简单
来自我的好朋友,EvilSay 投稿的文章。我稍微润色了一下,以下是原文: