无限极分类查找所有子孙节点的改进算法

在以前,遇到无限极分类返回一个节点的所有子孙节点时,我都是用递归计算的,后来发现时间复杂度和空间复杂度都太高了,后来自己研究了一下改进了算法.

节点数据如下:键值对分别是自己对应父亲节点

<?php
$tree=array(
1=>0,
2=>1,
3=>2,
4=>3,
5=>4,
6=>5,
7=>6,
8=>7,
9=>8,
10=>9,
11=>10,
);
?>

以往算法如下:

<?php
function get_list($tree,$id=0)
{
  static $list=array();//定义静态数组存放子孙
  foreach ($tree as $key => $v)
  {
        if($v==$id)
        {
            $list[]=$key;//把子孙放入数组中
            unset($tree[$key]);//去掉这个数组的键 避免无效循环
            get_list($tree,$key);//再次调用自身,把子节点变成父节点去寻找子孙
        }
    }
    return $list;//返回数组
}
?>

然而这样的算法在遇到节点层级非常深的时候会崩溃,例如超过100层,php会报错误的。后来改进了一种算法如下:

<?php
$id=2;

$new_array=array();//存放子孙的数组
$id_list[]=$id;//存放父亲的数组
//遍历所有子孙数据 每次去取已经有的数据的子孙 并把它加入父亲数组
for ($i=1; $i <= count($tree); $i++)
{
    foreach ($tree as $key => $v)
    {
        if( in_array($v,$id_list) )
        {
            $new_array[$key]=$v;//把我放进子孙数组
            $id_list[$key]=$key;//把子孙也放入父亲数组
            unset($tree[$key]);//这个已经用过了可以回收了避免无效循环
        }
    }
}
$son_list=array_keys($new_array);//拿到存放子孙的数组 取键即可
print_r($son_list);
exit();
?>
时间: 2024-08-06 03:39:55

无限极分类查找所有子孙节点的改进算法的相关文章

php 无限极分类查找家谱树

1:迭代的效率要比递归高,代码页相对少些,所以查找家谱树推荐用迭代 $area = array( array('id'=>1,'name'=>'安徽','parent'=>0), array('id'=>2,'name'=>'海淀','parent'=>7), array('id'=>3,'name'=>'濉溪县','parent'=>5), array('id'=>4,'name'=>'昌平','parent'=>7), array

thinkphp5.0无限极分类及格式化输出

首先我们来看数据表 从上图中可以发现,中国下有贵州,北京两个子节点,而北京有天安门一个子节点,纽约的子节点是"纽约的子类". 从pid为0看出,中国和纽约是顶级节点. 因为贵州的pid是1,而中国的id为1,所以贵州的父节点是中国,至于type字段,可以不用管,只是我自己的项目需要. 可以发现,着写数据在数据表中是无序的,并没有我们想象中的层次结构分明并且可读性很好. 那么,当使用无限极分类之后数据的输出是怎样的呢?如下: 这样就能够很清晰的看出他们的层次结构了,那么这样的效果在thi

PHP实现无限极分类的两种方式,递归和引用

面试的时候被问到无限极分类的设计和实现,比较常见的做法是在建表的时候,增加一个PID字段用来区别自己所属的分类 $array = array( array('id' => 1, 'pid' => 0, 'name' => '河北省'), array('id' => 2, 'pid' => 0, 'name' => '北京市'), array('id' => 3, 'pid' => 1, 'name' => '邯郸市'), array('id' =>

C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现之方法二:加入缓存机制

在上一篇文章中我用递归方法实现了管理菜单,在上一节我也提到要考虑用缓存,也算是学习一下.Net Core的缓存机制. 关于.Net Core的缓存,官方有三种实现: 1.In Memory Caching 我理解是在内容中实现,这种方法适用于单服务器的生产环境. 2.a Distributed Cache 分部式缓存实现. 3.Response Cache 这种方式我理解为客户端缓存. 今天我只用了第一种实现方法,内存中缓存,之所以用这种方法我是觉得我这里用缓存的初衷是为了减少访问数据库的次数,

递归的一些应用(二)无限极分类

用递归的方法实现无限极分类 通常我在写项目的时候,在写一些例如商城分类的时候会实现对应分类的上级分类,或者其它项目部门管理的上级部门的时候一般就会用到无限极分类来进行分类 第一步:首先在数据表设计的时候,如果要实现无限极分类,一般我会在数据表多添加一个字段pid,下面我通过一张新建的数据表来说明一下, (1)建表: -- ---------------------------- -- Table structure for pid -- ----------------------------

PHP无限极分类的实现(不使用递归)

无限极分类在开发中经常使用,例如:部门结构.文章分类.无限极分类的难点在于“输出”和“查询”,例如 将文章分类输出为<ul>列表形式: 查找分类A下面所有分类包含的文章. 1.实现原理 在<无限级分类实现思路>一文中介绍了几种常见的实现方法,各有利弊.其中“改进前序遍历树”数据结构,便于输出和查询,但是在移动分类和常规理解上有些复杂. 2.数据结构 id fid title 1 0 中国 2 1 江苏 3 1 安徽 4 8 江阴 5 3 芜湖 6 3 合肥 7 3 蚌埠 8 2 无

C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现

今天做一个管理后台菜单,想着要用无限极分类,记得园子里还是什么地方见过这种写法,可今天找了半天也没找到,没办法静下心来自己写了: 首先创建节点类(我给它取名:AdminUserTree): 1 /// <summary> 2 /// 无限极节点类 3 /// </summary> 4 public class AdminUserTree 5 { 6 /// <summary> 7 /// 节点信息 8 /// </summary> 9 public int

yii框架无限极分类的做法

用yii框架做了一个无限极分类,主要的数组转换都是粘贴的别人的代码,但还是不要脸的写出来,方便以后自己看 用的是递归,不是path路径 控制器: protected function subtree($arr,$id=0,$lev=1){ $subs = array(); // 子孙数组 foreach($arr as $v) { if($v['parent_id'] == $id) { $v['lev'] = $lev; $subs[] = $v; // 举例说找到array('id'=>1,

用递归的方法实现无限极分类

通常我在写项目的时候,在写一些例如商城分类的时候会实现对应分类的上级分类,或者其它项目部门管理的上级部门的时候一般就会用到无限极分类来进行分类 第一步:首先在数据表设计的时候,如果要实现无限极分类,一般我会在数据表多添加一个字段pid,下面我通过一张新建的数据表来说明一下, (1)建表: -- ---------------------------- -- Table structure for pid -- ---------------------------- DROP TABLE IF