PHP无限级分类实现:递归与迭代法构建子孙树与家谱树

Ruby
Ruby
发布时间:2026-10-14| 7人浏览过
原创

在处理后台管理、内容发布或目录导航等系统时,无限级分类是常见的数据结构需求。本文将探讨如何在 PHP 中通过数组处理无限级分类数据,分别演示利用递归构建深层级的子孙树,以及使用递归和迭代两种方式向上追溯的家谱树(路径回溯),帮助开发者理解不同场景下的算法选择。

结果与目标

在本地开发或数据处理阶段,我们通常面临将扁平的二维数组转换为具有层级关系的一维结构(用于下拉框或列表展示),或者需要根据当前节点ID反向获取其所有父级节点(用于面包屑导航)的需求。以下案例均基于同一组区域数据进行演示。

准备条件

假设数据库中有一张地区表,我们在 PHP 内存中将其加载为二维数组。parent 字段存储父级节点的 ID,0 表示顶级节点。数据结构如下:

$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('id'=>5,'name'=>'淮北','parent'=>1),
    array('id'=>6,'name'=>'朝阳','parent'=>7),
    array('id'=>7,'name'=>'北京','parent'=>0),
    array('id'=>8,'name'=>'上地','parent'=>2)
);

真实操作顺序

第1步:利用递归查找子孙树

目的:将所有指定根节点下的子节点按层级展开成单一的一维数组,常用于生成无限级下拉菜单或前端树形组件的数据源。

入口参数:$arr(数据源数组),$id(起始查找ID,默认为0即从根开始),$lev(当前层级深度)。

function subtree($arr,$id=0,$lev=1) {
    $subs = array(); // 子孙数组
    foreach($arr as $v) {
        if($v['parent'] == $id) {
            $v['lev'] = $lev;
            $subs[] = $v; // 找到直接子节点
            $subs = array_merge($subs,subtree($arr,$v['id'],$lev+1)); // 递归继续查找下级
        }
    }
    return $subs;
}
$tree = subtree($area,0,1);
foreach($tree as $v) {
    echo str_repeat('  ',$v['lev']),$v['name'],'<br />';
}

完成状态:执行后得到包含所有后代节点且带有 lev 属性标识层级的新数组,打印输出即为层级缩进效果。

第2步:利用递归求家谱树(路径回溯)

目的:给定任意一个节点 ID,获取从该节点到最顶级祖先节点的所有路径信息。此方法常用于渲染“首页 > 分类 > 子类”的面包屑导航。

function familytree($arr,$id) {
    $tree = array();
    foreach($arr as $v) {
        if($v['id'] == $id) { 
            if($v['parent'] > 0) { // parent>0说明还有上级
                $tree = array_merge($tree,familytree($arr,$v['parent']));
            }
            $tree[] = $v; 
        }
    }
    return $tree;
}
print_r(familytree($area,8)); // 预期输出: 北京-海淀-上地

注意:递归虽然逻辑直观,但如果分类层级极深,可能会消耗较多栈内存。

第3步:利用迭代求家谱树(推荐高效方案)

目的:在不牺牲代码可读性的前提下,避免递归带来的调用开销,适合层级较深的场景。

// 迭代方式找家谱树
function tree($arr,$id) {
    $tree = array();
    while($id !== 0) {
        foreach($arr as $v) {
            if($v['id'] == $id) {
                $tree[] = $v;
                $id = $v['parent'];
                break;
            } 
        }
    }
    return $tree;
}
print_r(tree($area,8));

关键区别:使用 while 循环不断定位当前 ID 的父亲节点,直到父亲 ID 为 0 为止。这种方法效率更高,代码逻辑同样清晰。

简要总结

以上就是PHP实现无限级分类并生成子孙树与家谱树的详细内容,更多关于PHP数据结构和算法优化的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。