前言
传统的递归生成树做法比较占用空间和时间,其原理是从根节点开始遍历数组去递归寻找当前节点的子节点,每个节点都需要深度递归挖掘,直到遍历完整个集合后才一层层返回收集结果,既耗时也费空间。本文将讲解如何使用数组引用巧妙生成树。:
需求
$arr_Device = 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),
);
预期结果
实例代码
/**
*无限极分类[,动态生成树][,数组引用生成树]
*/
$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),
);
//动态生成树
function getSubTree( $arr_ParamItems ){
//重构$arr_ParamItems数组
$arr_Item = array();
foreach( $arr_ParamItems as $i_Index => $arr_SubItem ){
$arr_Item[$arr_SubItem['id']] = $arr_SubItem;
unset( $arr_ParamItems[$i_Index] );
}
//生成树
$arr_Tree = array();
foreach( $arr_Item as &$arr_SubItem ){
if( isset( $arr_Item[$arr_SubItem['pid']] ) ){
$arr_Item[ $arr_SubItem['pid'] ]['sub'][] = &$arr_SubItem;
}else{
$arr_Tree[] = &$arr_SubItem;
}
}
return $arr_Tree;
}
print_r( getSubTree( $categories ) );
?>
代码解析一
此处引用了$arr_Item中的每个数组的地址,如果没有&符号则会变成值传递
代码解析二
此处表示把根节点(pid=0)的数组的地址赋值给$arr_Tree。如果没有&符号则会把当前根节点数组的值传递给$arr_Tree,这样$arr_Tree就会失去了与该根节点的联系
代码解析三
既然进入了这一层的判断则表示了当前节点非根节点了。那么必然存在父亲节点。此处引入巧妙的建立了父亲和儿子节点的关系,儿子节点把自己的地址给了父亲。
结束语
顺利理解本章内容需要了解PHP二维数组在内存中的创建原理,以及对地址的了解;还有PHP中foreach循环的地址引用原理。由于篇幅问题就不明细了,如果还有不明之处请单独私聊。希望本章能帮助到同胞们,谢谢大家(*^__^*)