瞭解無限極分類,首先要肯定其數據結構,而後從易到難,分別理解找子結點,找祖先結點,找子孫結點。
php
數據結構以下:數據結構
$arr=array( array('id'=>1,'name'=>'湖北','parent_id'=>0), array('id'=>2,'name'=>'武漢','parent_id'=>1), array('id'=>3,'name'=>'黃岡','parent_id'=>1), array('id'=>4,'name'=>'江西','parent_id'=>0), array('id'=>5,'name'=>'黃陂','parent_id'=>2), array('id'=>6,'name'=>'九江','parent_id'=>4), array('id'=>7,'name'=>'南昌','parent_id'=>4), array('id'=>8,'name'=>'研子','parent_id'=>5), array('id'=>9,'name'=>'羅田','parent_id'=>3));
最終的要效果以下:ide
湖北 武漢 黃陂 研子 黃岡 羅田 江西 九江 南昌
如今咱們從易到難,首先實現找子結點(直接子結點,不包含孫子結點)。某個結點與其子結點的聯繫在該結點的id等於子結點的parent_id。spa
例如給定 array('id'=>1,'name'=>'湖北','parent_id'=>0),其子結點爲:遞歸
array('id'=>2,'name'=>'武漢','parent_id'=>1)array('id'=>3,'name'=>'黃岡','parent_id'=>1)
按此邏輯,代碼以下:it
function sontree($arr,$cat_id){ $son=array(); foreach ($arr as $k => $v) { if($v['parent_id']==$cat_id){ $son[]=$v; } } return $son; }
接着來實現找祖先結點,A結點的parent_id等於B結點的id,則B結點是A結點的祖先,依次類推,直到某個祖先結點的parent_id=0時結束。例:A->B->C->D(D的parent_id=0),則A結點的祖先是B->C->D.依此邏輯,代碼以下:io
function fathertree34($arr,$id){ $father=array(); while($id>0){ foreach ($arr as $k => $v) { if($v['cat_id']==$id){ $father[]=$v; $id=$v['parent_id']; } } } return $father; }
最後來實現找子孫結點。前面已經實現了找子結點,子孫結點即在子結點的基礎上再找子結點,依次類推,直到沒有子結點爲止。依此邏輯,咱們能夠利用遞歸來實現,代碼以下:
function
function sub_tree($arr,$id,$lev=0){ static $sub=array(); foreach ($arr as $k => $v) { if($v['parent_id']==$id){ $v['lev']=$lev; $sub[]=$v; sub_tree($arr,$v['cat_id'],$lev+1); } } return $sub; }
$v['lev']=$lev;是用來記錄結點在子孫樹中的深度。class
找子孫結點也能夠使用棧來實現,代碼以下:基礎
function sub_tree($arr,$id){ $stack=array(); $sub=array(); foreach ($arr as $k => $v) { if($v['cat_id']==$id){ $stack[]=$v; } } while($stack){ $row=array_pop($stack); $sub[]=$row; foreach ($arr as $k => $v) { if($v['parent_id']==$row['cat_id']){ $stack[]=$v; } } } return $sub; }