多级树的遍历
class MultilevelTree
{
private $depth;//深度
private $i; //深度计数器
private static $db ; //数据库对象
public $arr; //节点数据数组
public $deep; //最大深度
function __construct($depth=0)
{
$this->depth = $depth;
$this->i = 0;
$this->arr = array();
$this->deep = 0;
}
static function instanceDb(){
if(!MultilevelTree::instanceDb()){
return new DB();
}else{
return MultilevelTree::instanceDb();
}
}
/**
* 左序遍历
* @param $uid 当前节点的id
*/
function traversal_left($uid){
$data = MultilevelTree::instanceDb()->query('select * from by_distribution where pid = '.$uid);
foreach ($data as $v){
if($v['uid']){
$this->arr[] = $v;
$this->traversal_left($v['uid']);
}
}
}
/**
* 根据层数遍历,并返回不包括本身的所有下层的数组
* @param $uid 当前节点的id
*/
function getChildren($uid){
$this->i++;
$data = MultilevelTree::instanceDb()->query('select * from by_distribution where pid = '.$uid);
$this->arr = array_merge($this->arr,$data);
if($this->depth > 0){
if($this->i == $this->depth){
$this->i=1; //每当纵向一条树线等于深度时,将深度计数器重置为1
return;
}
}
foreach ($data as $v){
if($v['uid']){
$this->getChildren($v['uid']);
}
}
}
/**
* 获取整棵树最大深度
* @param $uid 当前节点的id
*/
function getChildrenDepth($uid){
$this->i++;
$data = MultilevelTree::instanceDb()->query('select * from by_distribution where pid = '.$uid);
foreach ($data as $v){
if($v['uid']){
$data2 = MultilevelTree::instanceDb()->query('select * from by_distribution where pid = '.$v['uid']);
if(!$data2){
if($this->deep < $this->i) $this->deep = $this->i;
$this->i=1; //每当没有子节点时,将计数器重置为初始值+1
return;
}
$this->getChildrenDepth($v['uid']);
}
}
}
/**
* 获取父级数据
* @param $pid 当前节点的父级id
*/
function getParent($pid){
$parent = MultilevelTree::instanceDb()->row('select * from by_distribution where uid = '.$pid);
if($this->i == $this->depth){
return;
}
if($parent['pid'] == 0) array_push($this->arr,$parent);//根节点
if($parent['pid']){
array_push($this->arr,$parent);
$this->i++;
$this->getParent($parent['pid']);
}
}
}
单元测试
class TestMultilevelTree extends PHPUnit_Framework_TestCase
{
/**
* 获取子节点数量
*/
function testGetChildren(){
$mlt = new MultilevelTree();
$mlt->getChildren(1);
$this->assertEquals(11,count($mlt->arr));
}
/**
* 获取子节点最大深度
*/
function testGetChildrenDepth(){
$mlt = new MultilevelTree();
$mlt->getChildrenDepth(1);
$this->assertEquals(4,$mlt->deep);
}
/**
* 获取获取父节点
*/
function testGetParent(){
$mlt = new MultilevelTree(10);
$mlt->getParent(2);
$this->assertEquals(2,count($mlt->arr));
}
}