博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
创建树上每级节点与叶子节点的映射[PHP]
阅读量:6455 次
发布时间:2019-06-23

本文共 2096 字,大约阅读时间需要 6 分钟。

hot3.png

    建立这种映射关系在一些情况下是非常有用的; 在数据库中存层级结构数据 一种最简单的方式就是 id,pid,attributes... id是主键,pid是上级节点id,结构简单但使用起来就会比较麻烦;

    首先,某级节点的子节点或者说后代节点不好查找,查找深度为2以上的父节点 为了效率就需要将所有的数据取出来迭代;虽然有这诸多麻烦,但这种结构维护起来确实非常方便;

    好了,进入正题,问题并不是很麻烦,设想一种情况,多层级分类只有叶子节点关联数据,而需要用户点击一个节点(无论是父级还是叶子)都能取出相关的关联数据,那么建立这种关系放在redis等kv nosql数据库中使用起来就会非常方便,先上代码

private function _createMap(){    $connection = Yii::app()->db;    $sql = "SELECT id,pid FROM {
{nodes}}";    $command = $connection->createCommand($sql);    $dataReader = $command->query();          $rows = array();    //struct 子节点 => 父节点    foreach($dataReader as $row){        $rows[$row['id']] = $row['pid'];    }    $map = array();    while(!empty($rows)){        foreach($rows as $key=>$value){            if(!in_array($key,$rows)){                if(!isset($map[$value])) $map[$value] = array();                if(!empty($map[$key])){                    $map[$value] = array_merge($map[$value],$map[$key]);                }else{                    $map[$value][] = $key;                }                unset($rows[$key]);            }        }    }    foreach($map[0] as $v){        $map[$v]=array($v);    }    unset($map[0]);              return $map;}

这里为了简单直接使用了Yii 的DAO 操作数据库;由于PHP数组的强大秒杀一切LinkedHashMap之类的东东;要充分使用这个优势,

代码中的$rows 是 '子节点'=>'父节点'的数组;$map是最后的结果 '节点'=>array(后代节点中的叶子节点);

下面来一个假设的$rows

$rows =array(    array('id'=>1,'pid'=>0),    array('id'=>2,'pid'=>1),    array('id'=>3,'pid'=>2),    array('id'=>4,'pid'=>3),    array('id'=>5,'pid'=>4),    array('id'=>9,'pid'=>4));

每次foreach将会取出$row里id不再pid里面的节点(当前的叶子节点) 存到$map中,然后unset;这样一次while循环之后就会把id为5,9的元素unset在$map中就会增加array(4=>array(5,9));下一次就会是id为4的依次类推,

到这里,你可能就会发现一个问题,就是如果照这样下去$map 只会存在每层节点的子节点而不是后代节点的叶子节点,所以在存到$map之前要先去判断一下这个id在$map中是否存在了,如果有就需要array_merge让其转换为叶子节点,这样问题就解决了;

下面贴出$map的最后结果;

array(    4 => array(5,9),    3 => array(5,9),    2 => array(5,9),    1 => array(5,9),    5 => array(5),    9 => array(9))

$map[0](pid=0)的为根节点 会存整棵树的叶子节点,将这些叶子节点转换为同样的结构便于使用;查询的时候可以根据ID取出ids OR查询(据说会比IN快一些,没有测试过);

问题并不是很复杂,只适用单父节点的树结构上,我觉得以上是创建这种映射比较快的一种方式,希望不会在 玩算法的高手面前贻笑大方;

转载于:https://my.oschina.net/empty125/blog/206116

你可能感兴趣的文章
NavigationController的使用
查看>>
多线程编程之Windows环境下创建新线程
查看>>
CentOS 7使用systemctl如何补全服务名称
查看>>
Unity3D NGUI 给button按钮添加单间事件
查看>>
密码的校验.大小写字母,数字,特殊字符中的至少3种
查看>>
ios 不同sdk4.3 6.0版本号,关于方法的兼容性的通用方法
查看>>
Shell编程学习总结
查看>>
构建之法阅读笔记02
查看>>
Webstorm常用快捷键备忘
查看>>
js滚动加载到底部
查看>>
Redis慢查询,redis-cli,redis-benchmark,info
查看>>
Virtualbox 虚拟机网络不通
查看>>
java概念基础笔记整理
查看>>
CC_UNUSED_PARAM 宏含义的解释
查看>>
leetcode124二叉树最大路径和
查看>>
AngularJS笔记整理 内置指令与自定义指令
查看>>
shell与正则表达式
查看>>
第三篇:白话tornado源码之请求来了
查看>>
表示数值的字符串
查看>>
JQUERY AJAX请求
查看>>