发布两个不用递归的树形数组构造函数 本帖最后由 xuzuning 于 2011-07-28 19:15:07 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 版主的示例写错了一点点 $data; 数据结构中的ID去掉岂不是更好 不仅少一次循环 还从语法层面拒绝了ID重复的可能function find_child($ar, $pid='pid') { foreach ($ar as $k => $item){ if( $item[$pid] ) { $ar[$item[$pid]]['child'][$k] = &$ar[$k]; } } return $ar;}function find_parent($ar,$pid='pid') { foreach ($ar as $k => $item){ if( $item[$pid] ){ if( ! isset($ar[$item[$pid]]['parent'][$item[$pid]]) ) $ar[$k]['parent'][$item[$pid]] =& $ar[$item[$pid]]; } } return $ar;}源数据结构变成$data = array( 1=>array('PARENT'=>0, 'NAME'=>'祖父'), 2=>array('PARENT'=>1, 'NAME'=>'父亲'), 3=>array('PARENT'=>1, 'NAME'=>'叔伯'), 4=>array('PARENT'=>2, 'NAME'=>'自己'), 5=>array('PARENT'=>4, 'NAME'=>'儿子'));$p = find_parent($data2, 'PARENT');$c = find_child($data2, 'PARENT'); 这两个函数对数组的顺序有要求:可以试一下:$data = array( array('ID'=>5, 'PARENT'=>4, 'NAME'=>'d'), array('ID'=>1, 'PARENT'=>0, 'NAME'=>'x'), array('ID'=>2, 'PARENT'=>1, 'NAME'=>'y'), array('ID'=>3, 'PARENT'=>1, 'NAME'=>'z'), array('ID'=>4, 'PARENT'=>2, 'NAME'=>'c'),);或者:$data = array( array('ID'=>1, 'PARENT'=>0, 'NAME'=>'a'), array('ID'=>2, 'PARENT'=>1, 'NAME'=>'b'), array('ID'=>3, 'PARENT'=>5, 'NAME'=>'c'), array('ID'=>4, 'PARENT'=>2, 'NAME'=>'d'), array('ID'=>5, 'PARENT'=>1, 'NAME'=>'e'),);$data = array( array('ID'=>1, 'PARENT'=>0, 'NAME'=>'1'), array('ID'=>2, 'PARENT'=>1, 'NAME'=>'11'), array('ID'=>3, 'PARENT'=>5, 'NAME'=>'12'), array('ID'=>4, 'PARENT'=>2, 'NAME'=>'111'), array('ID'=>5, 'PARENT'=>1, 'NAME'=>'1111'),); $data = array( array('id'=>1, 'pid'=>0, 'NAME'=>'a'), array('id'=>2, 'pid'=>1, 'NAME'=>'b'), array('id'=>3, 'pid'=>5, 'NAME'=>'c'), array('id'=>4, 'pid'=>2, 'NAME'=>'d'), array('id'=>5, 'pid'=>1, 'NAME'=>'e'),);$c = find_child($data);id = 1 子孙 ( $c[1] )Array( [id] => 1 [pid] => 0 [NAME] => a [child] => Array ( [2] => Array ( [id] => 2 [pid] => 1 [NAME] => b [child] => Array ( [4] => Array ( [id] => 4 [pid] => 2 [NAME] => d ) ) ) [5] => Array ( [id] => 5 [pid] => 1 [NAME] => e [child] => Array ( [3] => Array ( [id] => 3 [pid] => 5 [NAME] => c ) ) ) ))id = 5 子孙 ( $c[5] )Array( [id] => 5 [pid] => 1 [NAME] => e [child] => Array ( [3] => Array ( [id] => 3 [pid] => 5 [NAME] => c ) ))么有问题呀!?你是还未理解结果的含义吧? ,,奥妙在于 &注意函数名find_parent, find_child,并非构造整个上下级树 不懂等看完整本PHP书后。再过来LOOK 下。 不过去掉 & 也可以哦? 真妙, 是不是就是用 & 累加覆盖 无须递归的树,我的做法是:id,rootid,level(本节点在本树的层次),order(本节点在本树的顺序)这种方式,输出树 最简单高效,一个select * from tb where ... order by rootid,order就行了插入节点会麻烦一点 树的实现太多了,js,jquery,extjs,dojo到处都有,顶lz UBB 内容存入剪贴板 学习中 php 我还不清楚 没用过 学习一下 /** * 创建父节点树形数组 * 参数 * $ar 数组,邻接列表方式组织的数据 * $id 数组中作为主键的下标或关联键名 * $pid 数组中作为父键的下标或关联键名 * 返回 多维数组 **/function find_parent($ar, $id='id', $pid='pid') { foreach($ar as $v) $t[$v[$id]] = $v; foreach ($t as $k => $item){ if( $item[$pid] ){ if( ! isset($t[$item[$pid]]['parent'][$item[$pid]]) ) $t[$item[$id]]['parent'][$item[$pid]] =& $t[$item[$pid]]; } } return $t;}/** * 创建子节点树形数组 * 参数 * $ar 数组,邻接列表方式组织的数据 * $id 数组中作为主键的下标或关联键名 * $pid 数组中作为父键的下标或关联键名 * 返回 多维数组 **/function find_child($ar, $id='id', $pid='pid') { foreach($ar as $v) $t[$v[$id]] = $v; foreach ($t as $k => $item){ if( $item[$pid] ) { $t[$item[$pid]]['child'][$item[$id]] =& $t[$k]; } } return $t;} 顶搂主,数组在php里面非常灵活.但是有几个疑问1.函数1中有一段代码copy如下if( ! isset($t[$item[$pid]]['parent'][$item[$pid]]) ) $t[$item[$id]]['parent'][$item[$pid]] =& $t[$item[$pid]];1) $t[$item[$id]]['parent'][$item[$pid]] =& $t[$item[$pid]];为什么不写成 $t[$item[$id]]['parent'] =& $t[$item[$pid]];难道树中一个节点有几个父节点?2)if( ! isset($t[$item[$pid]]['parent'][$item[$pid]]) ) 我认为这个判断永远成立这个问题是跟1)中是一样的,parent后面接的是自己的id还是pid呢?从$t[$item[$id]]['parent'][$item[$pid]] =& $t[$item[$pid]];中看到是pid从if中看到的是自己的id,所以这里和1)是一样的. 废话了2.为什么不把两个函数合并,这样不是即可以找父节点,也可以找子节点列表?3.既然是树,肯定要遍历. 但是我找不到根在哪,是否需要返回一个根id呢?有了根id和数组写个二维数组就可以遍历了 find_parent理解了,find_child有点没懂。 请大侠指点一下个 & 我也深知奥妙在于此,但是实在是想不通啊 如何写一个规则 处理文章URL地址 php mysql 缓存问题? 做小偷程序 先POST变量 然后获取页面 这个子查询的语句该怎么写? form 中 select 值用下面的 javascript 取的值,如何确定一个 默认 selected 请问各们我这里哪错了 哪位兄弟有php.net的资料,共享给俺学学。。。 终于升星了,散分;同时说说我的成星历程,欢迎捧场,畅所欲言~ 创意? 哪位知道有好的PHP空间商用空间?能承受上百人的负荷。谢谢了,急用! PHP能否把下载文件以纯数据的形式提供下载(或者存到数据库中)? 请问win7下如何配置IIS使其作为一个php虚拟站点
function find_child($ar, $pid='pid') {
foreach ($ar as $k => $item){
if( $item[$pid] ) {
$ar[$item[$pid]]['child'][$k] = &$ar[$k];
}
}
return $ar;
}
function find_parent($ar,$pid='pid') {
foreach ($ar as $k => $item){
if( $item[$pid] ){
if( ! isset($ar[$item[$pid]]['parent'][$item[$pid]]) )
$ar[$k]['parent'][$item[$pid]] =& $ar[$item[$pid]];
}
}
return $ar;
}
源数据结构变成$data = array(
1=>array('PARENT'=>0, 'NAME'=>'祖父'),
2=>array('PARENT'=>1, 'NAME'=>'父亲'),
3=>array('PARENT'=>1, 'NAME'=>'叔伯'),
4=>array('PARENT'=>2, 'NAME'=>'自己'),
5=>array('PARENT'=>4, 'NAME'=>'儿子')
);$p = find_parent($data2, 'PARENT');
$c = find_child($data2, 'PARENT');
$data = array(
array('ID'=>5, 'PARENT'=>4, 'NAME'=>'d'),
array('ID'=>1, 'PARENT'=>0, 'NAME'=>'x'),
array('ID'=>2, 'PARENT'=>1, 'NAME'=>'y'),
array('ID'=>3, 'PARENT'=>1, 'NAME'=>'z'),
array('ID'=>4, 'PARENT'=>2, 'NAME'=>'c'),
);或者:
$data = array(
array('ID'=>1, 'PARENT'=>0, 'NAME'=>'a'),
array('ID'=>2, 'PARENT'=>1, 'NAME'=>'b'),
array('ID'=>3, 'PARENT'=>5, 'NAME'=>'c'),
array('ID'=>4, 'PARENT'=>2, 'NAME'=>'d'),
array('ID'=>5, 'PARENT'=>1, 'NAME'=>'e'),
);
$data = array(
array('ID'=>1, 'PARENT'=>0, 'NAME'=>'1'),
array('ID'=>2, 'PARENT'=>1, 'NAME'=>'11'),
array('ID'=>3, 'PARENT'=>5, 'NAME'=>'12'),
array('ID'=>4, 'PARENT'=>2, 'NAME'=>'111'),
array('ID'=>5, 'PARENT'=>1, 'NAME'=>'1111'),
);
array('id'=>1, 'pid'=>0, 'NAME'=>'a'),
array('id'=>2, 'pid'=>1, 'NAME'=>'b'),
array('id'=>3, 'pid'=>5, 'NAME'=>'c'),
array('id'=>4, 'pid'=>2, 'NAME'=>'d'),
array('id'=>5, 'pid'=>1, 'NAME'=>'e'),
);
$c = find_child($data);
id = 1 子孙 ( $c[1] )
Array
(
[id] => 1
[pid] => 0
[NAME] => a
[child] => Array
(
[2] => Array
(
[id] => 2
[pid] => 1
[NAME] => b
[child] => Array
(
[4] => Array
(
[id] => 4
[pid] => 2
[NAME] => d
) ) ) [5] => Array
(
[id] => 5
[pid] => 1
[NAME] => e
[child] => Array
(
[3] => Array
(
[id] => 3
[pid] => 5
[NAME] => c
) ) ) ))
id = 5 子孙 ( $c[5] )
Array
(
[id] => 5
[pid] => 1
[NAME] => e
[child] => Array
(
[3] => Array
(
[id] => 3
[pid] => 5
[NAME] => c
) ))
么有问题呀!?
你是还未理解结果的含义吧?
id,rootid,level(本节点在本树的层次),order(本节点在本树的顺序)这种方式,输出树 最简单高效,一个select * from tb where ... order by rootid,order就行了
插入节点会麻烦一点
* 创建父节点树形数组
* 参数
* $ar 数组,邻接列表方式组织的数据
* $id 数组中作为主键的下标或关联键名
* $pid 数组中作为父键的下标或关联键名
* 返回 多维数组
**/
function find_parent($ar, $id='id', $pid='pid') {
foreach($ar as $v) $t[$v[$id]] = $v;
foreach ($t as $k => $item){
if( $item[$pid] ){
if( ! isset($t[$item[$pid]]['parent'][$item[$pid]]) )
$t[$item[$id]]['parent'][$item[$pid]] =& $t[$item[$pid]];
}
}
return $t;
}
/**
* 创建子节点树形数组
* 参数
* $ar 数组,邻接列表方式组织的数据
* $id 数组中作为主键的下标或关联键名
* $pid 数组中作为父键的下标或关联键名
* 返回 多维数组
**/
function find_child($ar, $id='id', $pid='pid') {
foreach($ar as $v) $t[$v[$id]] = $v;
foreach ($t as $k => $item){
if( $item[$pid] ) {
$t[$item[$pid]]['child'][$item[$id]] =& $t[$k];
}
}
return $t;
}
但是有几个疑问
1.函数1中有一段代码copy如下
if( ! isset($t[$item[$pid]]['parent'][$item[$pid]]) )
$t[$item[$id]]['parent'][$item[$pid]] =& $t[$item[$pid]];
1) $t[$item[$id]]['parent'][$item[$pid]] =& $t[$item[$pid]];
为什么不写成 $t[$item[$id]]['parent'] =& $t[$item[$pid]];
难道树中一个节点有几个父节点?2)if( ! isset($t[$item[$pid]]['parent'][$item[$pid]]) ) 我认为这个判断永远成立
这个问题是跟1)中是一样的,parent后面接的是自己的id还是pid呢?
从$t[$item[$id]]['parent'][$item[$pid]] =& $t[$item[$pid]];中看到是pid
从if中看到的是自己的id,所以这里和1)是一样的. 废话了2.为什么不把两个函数合并,这样不是即可以找父节点,也可以找子节点列表?3.既然是树,肯定要遍历. 但是我找不到根在哪,是否需要返回一个根id呢?
有了根id和数组写个二维数组就可以遍历了
find_child有点没懂。
请大侠指点一下个 & 我也深知奥妙在于此,但是实在是想不通啊