本帖最后由 xuzuning 于 2011-07-28 19:15:07 编辑

解决方案 »

  1.   

    版主的示例写错了一点点  $data;
      

  2.   

    数据结构中的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');
      

  3.   

    这两个函数对数组的顺序有要求:可以试一下:
    $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'),
    );
      

  4.   

    $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
                    )        ))
    么有问题呀!?
    你是还未理解结果的含义吧?
      

  5.   

    ,,奥妙在于 &注意函数名find_parent, find_child,并非构造整个上下级树
      

  6.   

    不懂等看完整本PHP书后。再过来LOOK 下。
      

  7.   

    不过去掉 & 也可以哦?
      

  8.   

    真妙, 是不是就是用   &  累加覆盖  
      

  9.   

    无须递归的树,我的做法是:
    id,rootid,level(本节点在本树的层次),order(本节点在本树的顺序)这种方式,输出树 最简单高效,一个select * from tb where ... order by rootid,order就行了
    插入节点会麻烦一点
      

  10.   

    树的实现太多了,js,jquery,extjs,dojo到处都有,顶lz
      

  11.   

    UBB   内容存入剪贴板
      

  12.   

    学习中   php 我还不清楚 没用过   学习一下 
      

  13.   

    /**
     * 创建父节点树形数组
     * 参数
     * $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;
    }
      

  14.   

    顶搂主,数组在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和数组写个二维数组就可以遍历了
      

  15.   

    find_parent理解了,
    find_child有点没懂。
      

  16.   


    请大侠指点一下个 &   我也深知奥妙在于此,但是实在是想不通啊