php 无限级分类就像是一棵树,这棵树有自己的根部,然后主干,枝干在到叶子,越是向前越茂密 家谱树是无限极分类的表现形式之一,另一个是子孙树。 从某个节点开始向上寻找其父节点,再找父节点的父节点,直到找不到为止

。按照这种寻找,形成的一个类似树状的结构,就叫做家谱树。 而子孙树与其相反,子孙树类似于生物书中的遗传图,从某个节点开始寻找它的子节点,再找子节点的子节点,直到寻找完毕。这样形成的树状结构就叫做子孙树。

子孙树

$categories = array(

   array('id'=>1,'name'=>'电脑','pid'=>0),

   array('id'=>2,'name'=>'手机','pid'=>0),

   array('id'=>3,'name'=>'笔记本','pid'=>1),

   array('id'=>4,'name'=>'台式机','pid'=>1),

   array('id'=>5,'name'=>'智能机','pid'=>2),

   array('id'=>6,'name'=>'功能机','pid'=>2),

   array('id'=>7,'name'=>'超级本','pid'=>3),

   array('id'=>8,'name'=>'游戏本','pid'=>3),

);

$tree = array();

//将分类id作为数组key,并创建son单元

foreach($categories as $category){

   $tree[$category['id']] = $category;

   $tree[$category['id']]['son'] = array();

}

//利用引用,将每个分类添加到父类son数组中,这样一次遍历即可形成树形结构。

foreach ($tree as $k=>$item) {

   if ($item['pid'] != 0) {

       $tree[$item['pid']]['son'][] = &$tree[$k];

   }

}

print_r($tree);

Array

(

   [1] => Array

       (

           [id] => 1

           [name] => 电脑

           [pid] => 0

           [son] => Array

               (

                   [0] => Array

                       (

                           [id] => 3

                           [name] => 笔记本

                           [pid] => 1

                           [son] => Array

                               (

                                   [0] => Array

                                       (

                                           [id] => 7

                                           [name] => 超级本

                                           [pid] => 3

                                           [son] => Array

                                               (

                                               )

                                       )

                                   [1] => Array

                                       (

                                           [id] => 8

                                           [name] => 游戏本

                                           [pid] => 3

                                           [son] => Array

                                               (

                                               )

                                       )

                               )

                       )

                   [1] => Array

                       (

                           [id] => 4

                           [name] => 台式机

                           [pid] => 1

                           [son] => Array

                               (

                               )

                       )

               )

       )

   [2] => Array

       (

           [id] => 2

           [name] => 手机

           [pid] => 0

           [son] => Array

               (

                   [0] => Array

                       (

                           [id] => 5

                           [name] => 智能机

                           [pid] => 2

                           [son] => Array

                               (

                               )

                       )

                   [1] => Array

                       (

                           [id] => 6

                           [name] => 功能机

                           [pid] => 2

                           [son] => Array

                               (

                               )

                       )

               )

       )

   [3] => Array

       (

           [id] => 3

           [name] => 笔记本

           [pid] => 1

           [son] => Array

               (

                   [0] => Array

                       (

                           [id] => 7

                           [name] => 超级本

                           [pid] => 3

                           [son] => Array

                               (

                               )

                       )

                   [1] => Array

                       (

                           [id] => 8

                           [name] => 游戏本

                           [pid] => 3

                           [son] => Array

                               (

                               )

                       )

               )

       )

   [4] => Array

       (

           [id] => 4

           [name] => 台式机

           [pid] => 1

           [son] => Array

               (

               )

       )

   [5] => Array

       (

           [id] => 5

           [name] => 智能机

           [pid] => 2

           [son] => Array

               (

               )

       )

   [6] => Array

       (

           [id] => 6

           [name] => 功能机

           [pid] => 2

           [son] => Array

               (

               )

       )

   [7] => Array

       (

           [id] => 7

           [name] => 超级本

           [pid] => 3

           [son] => Array

               (

               )

       )

   [8] => Array

       (

           [id] => 8

           [name] => 游戏本

           [pid] => 3

           [son] => Array

               (

               )

       )

)

// 递归函数的三种实现方式:引用做参数 全局变量 静态变量


function tree($items){

   $tree=array();

   $packData=array();

   foreach ($items as  $data) {

       $packData[$data['id']] = $data;

   }

   foreach ($packData as $key =>$val){    

       if($val['pid']==0){//代表跟节点      

           $tree[]=& $packData[$key];

       }else{

           //找到其父类

           $packData[$val['pid']]['son'][]=& $packData[$key];

       }

   }

   return $tree;

}

function getTree($data, $pId)

{

$tree = [];

foreach($data as $k => $v)

{

 if($v['pid'] == $pId){        

  //父亲找到儿子

  $v['son'] = getTree($data, $v['id']);

  $tree[] = $v;

  //unset($data[$k]);

 }

}

return $tree;

}

$tree = getTree($categories, 0);

print_r($tree);

Array

(

   [0] => Array

       (

           [id] => 1

           [name] => 电脑

           [son] => Array

               (

                   [0] => Array

                       (

                           [id] => 3

                           [name] => 笔记本

                           [son] => Array

                               (

                                   [0] => Array

                                       (

                                           [id] => 7

                                           [name] => 超级本

                                           [son] => Array

                                               (

                                               )

                                       )

                                   [1] => Array

                                       (

                                           [id] => 8

                                           [name] => 游戏本

                                           [son] => Array

                                               (

                                               )

                                       )

                               )

                       )

                   [1] => Array

                       (

                           [id] => 4

                           [name] => 台式机

                           [son] => Array

                               (

                               )

                       )

               )

       )

   [1] => Array

       (

           [id] => 2

           [name] => 手机

           [son] => Array

               (

                   [0] => Array

                       (

                           [id] => 5

                           [name] => 智能机

                           [son] => Array

                               (

                               )

                       )

                   [1] => Array

                       (

                           [id] => 6

                           [name] => 功能机

                           [son] => Array

                               (

                               )

                       )

               )

       )

)

function genTree2($items) {

   foreach ($items as $item)

       $items[$item['pid']]['son'][$item['id']] = &$items[$item['id']];

   return isset($items[0]['son']) ? $items[0]['son'] : array();

}

function genTree3($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;

}


家谱树

function subtree($arr,$id=0,$lev=1) {

   $subs = array(); // 子孙数组

   foreach($arr as $v) {

       if($v['pid'] == $id) {

           $v['lev'] = $lev;

           $subs[] = $v;

           $subs = array_merge($subs,subtree($arr,$v['id'],$lev+1));

       }

   }

   return $subs;

}

print_r(subtree($categories,1));

Array

(

   [0] => Array

       (

           [id] => 3

           [name] => 笔记本

           [pid] => 1

           [lev] => 1

       )

   [1] => Array

       (

           [id] => 7

           [name] => 超级本

           [pid] => 3

           [lev] => 2

       )

   [2] => Array

       (

           [id] => 8

           [name] => 游戏本

           [pid] => 3

           [lev] => 2

       )

   [3] => Array

       (

           [id] => 4

           [name] => 台式机

           [pid] => 1

           [lev] => 1

       )

)

function familytree($arr,$id) {

   $tree = array();

   while($id !== 0) {

       foreach($arr as $v) {

           if($v['id'] == $id) {

               $tree[] = $v;

               $id = $v['pid'];

               break;

           }    

       }

   }

   return $tree;

}

function familytree2($arr,$id) {

   $tree = array();

   foreach($arr as $v) {

       if($v['id'] == $id) {// 判断要不要找父栏目

           if($v['pid'] > 0) { // 说明有父栏目

               $tree = array_merge($tree,familytree($arr,$v['pid']));

           }

           $tree[] = $v;

       }

   }

   return $tree;

}

print_r(familytree($categories,4));

Array

(

   [0] => Array

       (

           [id] => 1

           [name] => 电脑

           [pid] => 0

       )

   [1] => Array

       (

           [id] => 4

           [name] => 台式机

           [pid] => 1

       )

)

function tree($list, $parent_id, $level=0) {

       //应该是静态的局部变量,这样才能保证,在递归调用时,所有

       //的tree方法,操作的是一个Tree空间。

       static $tree = array();//保存找到的分类的数组

       //遍历所有分类,通过parent_id判断,哪些是我们正在查找的

       foreach($list as $row) {

           //判断当前所遍历的分类$row, 是否是当前需要查找的子分类

           if($row['pid'] == $parent_id) {

               //找到了一个分类

               $row['level'] = $level;

               $tree[] = $row;

               //继续查找当前$row所代表的分类的子分类

               tree($list, $row['id'], $level+1);

           }

       }

       return $tree;

   }

print_r(tree($categories,'pid'));

Array

(

   [0] => Array

       (

           [id] => 1

           [name] => 电脑

           [pid] => 0

           [level] => 0

       )

   [1] => Array

       (

           [id] => 3

           [name] => 笔记本

           [pid] => 1

           [level] => 1

       )

   [2] => Array

       (

           [id] => 7

           [name] => 超级本

           [pid] => 3

           [level] => 2

       )

   [3] => Array

       (

           [id] => 8

           [name] => 游戏本

           [pid] => 3

           [level] => 2

       )

   [4] => Array

       (

           [id] => 4

           [name] => 台式机

           [pid] => 1

           [level] => 1

       )

   [5] => Array

       (

           [id] => 2

           [name] => 手机

           [pid] => 0

           [level] => 0

       )

   [6] => Array

       (

           [id] => 5

           [name] => 智能机

           [pid] => 2

           [level] => 1

       )

   [7] => Array

       (

           [id] => 6

           [name] => 功能机

           [pid] => 2

           [level] => 1

       )

)


$ids = array_column($categories,'pid','id');

Array

(

   [1] => 0

   [2] => 0

   [3] => 1

   [4] => 1

   [5] => 2

   [6] => 2

   [7] => 3

   [8] => 3

)

$id = 7;

while($ids[$id]) {

   $id = $ids[$id];

}

echo $id; // 1